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
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
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.