Search code examples
androidfirebasekotlinfirebase-realtime-database

How can I check whether all children have been iterated in Realtime Database?


I wanted to make sure that none of my user has a certain mobile number in Firebase Realtime Database.

I know how to check if one of them has the phone number with the following code:

databaseReferenceUser.addListenerForSingleValueEvent(object: ValueEventListener {
    override fun onDataChange(snapshot: DataSnapshot) {
        if (snapshot.exists()) {
            for (ds in snapshot.getChildren()) {
                if (ds.child("MobileNo").getValue().toString() == binding.phoneNumberInput.text.toString()) {
                    ds.child("school").child(uid!!).child("schoolUid").getRef().setValue(uid)
                    ds.child("school").child(uid).child("timestamp").getRef().setValue(timestamp)
                    ds.child("school").child(uid).child("userIdForSchool").getRef().setValue(idDealerFactory)
                    ds.child("school").child(uid).child("schoolName").getRef().setValue(namaPerusahaan)
                    ds.child("school").child(uid).child("schoolCode").getRef().setValue(codeFactory)
                }

            }
        }
    }

    override fun onCancelled(error: DatabaseError) {
    }
})

I wanted to do something (create a new profile) when none of the children in for (ds in snapshot.getChildren()) { } has the phone number.

How to do that?

Do I need to do it manually by declaring a new boolean variable, such as, var newPhoneNumber = False or Firebase Realtime Database has an API for this?

Here is the data example:

{
  "student": {
    "0JIuZsasu0pOgnYpZNiWg": {
      "MobileNo": "0512216518",
      "SchoolUid": "soiuhgOIaoefi23",
      "timestamp": "65113215454565",
      "userIdForSchool": "aieuhfIUoaef23244,
      "schoolName": "St Josh",
      "schoolCode": "SJH"
    },
    "Iuisefhiub45oids78BJn": {
      "MobileNo": "0542657518",
      "SchoolUid": "soiuhgOIaoefi23",
      "timestamp": "65113215433235",
      "userIdForSchool": "seiuhfIiasf89i23A,
      "schoolName": "St Josh",
      "schoolCode": "SJH"
    },
    "QPOcsiue632baifd2nkJ": {
      "MobileNo": "0712218818",
      "SchoolUid": "soiuhgOIaoefi23",
      "timestamp": "65113215454445",
      "userIdForSchool": "QOepfqjb39IKAhdai,
      "schoolName": "St Josh",
      "schoolCode": "SJH"
    }
  }
}

Thanks.


Solution

  • The easiest way to check for existence in your current code is to add a variable for tracking:

    val isFound: Boolean = false
    for (ds in snapshot.getChildren()) {
        if (ds.child("MobileNo").getValue().toString() == binding.phoneNumberInput.text.toString()) {
            isFound = true
            ds.child("school").child(uid!!).child("schoolUid").getRef().setValue(uid)
            ds.child("school").child(uid).child("timestamp").getRef().setValue(timestamp)
            ds.child("school").child(uid).child("userIdForSchool").getRef().setValue(idDealerFactory)
            ds.child("school").child(uid).child("schoolName").getRef().setValue(namaPerusahaan)
            ds.child("school").child(uid).child("schoolCode").getRef().setValue(codeFactory)
        }
    }
    print(isFound)
    

    If you have no use for the other user data, this is a bit wasteful though - and gets more wasteful as you add more users. Instead of loading all users to check if one exists, you can use a query to load only that user.

    val query = databaseReferenceUser.orderByChild("MobileNo").equalTo(binding.phoneNumberInput.text.toString())
    query.addListenerForSingleValueEvent(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {
                for (ds in snapshot.getChildren()) {
                    ds.child("school").child(uid!!).child("schoolUid").getRef().setValue(uid)
                    ds.child("school").child(uid).child("timestamp").getRef().setValue(timestamp)
                    ds.child("school").child(uid).child("userIdForSchool").getRef().setValue(idDealerFactory)
                    ds.child("school").child(uid).child("schoolName").getRef().setValue(namaPerusahaan)
                    ds.child("school").child(uid).child("schoolCode").getRef().setValue(codeFactory)
                }
                ...    
    

    Now the code doesn't need a check for the MobileNo anymore, because the database already handled that check.