Home > database >  Firebase Android - datasnapshot not returning all the fields in onChildChanged()
Firebase Android - datasnapshot not returning all the fields in onChildChanged()

Time:04-15

When my app loads, the datasnapshot returns all the fields in the child listener in the onChildAdded() method which is how I populate a local list variable called TaskGroups from the datasnapshot and below is the contents of that datasnapshot

taskGroupList={KYTD1647450187={taskGroupName=Task, taskGroupID=KYTD1647450187, taskGroupColorString=#FFFF0BFF}, AONS1647450187={taskGroupName=Fitness, taskGroupID=AONS1647450187, taskGroupColorString=#FF6E2E7B}, BNZH1648154782={taskGroupName=School, taskGroupID=BNZH1648154782, taskGroupColorString=#FF6E2E7C}

and here is what it looks like on Firebase before adding anything

enter image description here

But when I attempt to add a new "taskgroup" from my Android app (I just added new taskgroup "Apdjf" just for this example), all the correct fields are uploaded to Firebase shown in the image below

enter image description here

However in the onChildChanged() method of the same listener of my app, I don't receive all the fields for the new "taskgroup" that I just added. Instead I'm only getting the "taskGroupID" for the newly added taskgroup and missing the "taskGroupColorString" and the "taskGroupName" fields and I need all this info to rebuild a certain part of my app. Below is what my datasnapshot gives me

taskGroupList={HDCL1649906550={taskGroupID=HDCL1649906550}, KYTD1647450187={taskGroupName=Task, taskGroupID=KYTD1647450187, taskGroupColorString=#FFFF0BFF}, AONS1647450187={taskGroupName=Fitness, taskGroupID=AONS1647450187, taskGroupColorString=#FF6E2E7B}, BNZH1648154782={taskGroupName=School, taskGroupID=BNZH1648154782, taskGroupColorString=#FF6E2E7C}

What is going on?

This is the Java code that gets called when I add a new "TaskGroup" to the database

@Override
    public void onDataChange(DataSnapshot dataSnapshot) {
          for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
               if (childDataSnapshot.child("taskGroupList").getValue() != null) {
                    String taskGroupId = generateTaskGroupID();
                    childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupID").getRef().setValue(taskGroupId);
                    childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupColorString").getRef().setValue(finalDatabaseTaskGroupColorString[0]);
                    childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupName").getRef().setValue(taskGroupSelected);
                }
          }
                                            
    }

CodePudding user response:

You're performing three separate write operations in the code you shared here:

childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupID").getRef().setValue(taskGroupId);
childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupColorString").getRef().setValue(finalDatabaseTaskGroupColorString[0]);
childDataSnapshot.child("taskGroupList").child(taskGroupId).child("taskGroupName").getRef().setValue(taskGroupSelected);

If taskGroupId is a new unique ID, then the first call to setValue (setValue(taskGroupId)) generates an onChildAdded event, while the other two setValue calls generate onChildChanged events.

To prevent this from happening, you should add all child nodes in a single write operation, for example with:

Map<String,Object> values = new HashMap<>();
values.put("taskGroupID", taskGroupId);
values.put("taskGroupColorString", finalDatabaseTaskGroupColorString[0]);
values.put("taskGroupName", taskGroupSelected);

childDataSnapshot.child("taskGroupList").child(taskGroupId).setValue(values);

Now there's only a single write operation, so this will (if the taskGroupId is a new unique ID) only result in a single onChildAdded call with all three properties.

  • Related