简体   繁体   中英

How can I update key values in realtime database?

数据结构

I want to update key values when it removed, so I wrote codes below. These codes are in the Checkbox listener.

What I did first:

if(isChecked) {
    Long size = dataSnapshot.child("Bookmark").getChildrenCount();
    ref_h.child(userUid).child("Bookmark").child(Long.toString(size + 1)).setValue(diningUid);
} else {
    for (int i = 1; i <= dataSnapshot.child("Bookmark").getChildrenCount(); i++) {
        if (dataSnapshot.child("Bookmark").child(Integer.toString(i)).getValue().toString().equals(diningUid)) {
            dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
            isRemoved = true;
        }
        if(isRemoved) {
            if(i != dataSnapshot.child("Bookmark").getChildrenCount()){
                String newDiningUid;
                newDiningUid = dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString();
                Log.d("newUID", newDiningUid);
                ref_h.child(userUid).child("Bookmark").child(Integer.toString(i)).setValue(newDiningUid);
            } else {
                dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
            }
        }
    }
}

But when the Checkbox status changes rapidly, key values are messed up. like this

data structure 2

Then I fixed the code with try-catch phrase.

if(isChecked) {//if not checked before listener runs, add to bookmark
    Long size = dataSnapshot.child("Bookmark").getChildrenCount();
    ref_h.child(userUid).child("Bookmark").child(Long.toString(size + 1)).setValue(diningUid);
} else {//if checked before listener runs, remove from bookmark
    for (int i = 1; i <= dataSnapshot.child("Bookmark").getChildrenCount(); i++) {
        try {
            if (dataSnapshot.child("Bookmark").child(Integer.toString(i)).getValue().toString().equals(diningUid)) {
                dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
                isRemoved = true;
            }
        } catch (NullPointerException e) {
            if (dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString().equals(diningUid)) {
                dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getRef().removeValue();
                isRemoved = true;
            }
        }
        if(isRemoved) {
            //update afterward value's index
            if(i != dataSnapshot.child("Bookmark").getChildrenCount()){
                String newDiningUid;
                newDiningUid = dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getValue().toString();
                ref_h.child(userUid).child("Bookmark").child(Integer.toString(i)).setValue(newDiningUid);
            } else {//remove last value
                try {
                    dataSnapshot.child("Bookmark").child(Integer.toString(i)).getRef().removeValue();
                } catch (NullPointerException e) {
                    dataSnapshot.child("Bookmark").child(Integer.toString(i + 1)).getRef().removeValue();
                }
            }
        }
    }
}

But I don't think I solved this problem. How can I update key values properly? or do I need to add a delay to Checkbox? or change the data structure?

The best solution is to not use sequential numeric keys, but rely on Firebase's push IDs. For reasons on why this is a better approach and how they work, see these classic Firebase blog posts:

If you insist on using array-like keys, you will have to use a transaction on the entire bookmark node to determine the next index. This is the only way to prevent the race condition that you now encounter when the array contents frequently change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM