Как я могу обновить значения ключей в базе данных реального времени?

#android #firebase #firebase-realtime-database

# #Android #firebase #firebase-realtime-database

Вопрос:

структура данных

Я хочу обновлять значения ключей при их удалении, поэтому я написал коды ниже. Эти коды находятся в прослушивателе флажков.

Что я сделал в первую очередь :

 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();
            }
        }
    }
}
 

Но когда статус флажка быстро меняется, значения ключей перепутаны.
вот так

структура данных 2

Затем я исправил код с помощью фразы try-catch.

 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();
                }
            }
        }
    }
}
 

Но я не думаю, что решил эту проблему.
Как я могу правильно обновить значения ключей?
или мне нужно добавить задержку в флажок?
или изменить структуру данных?

Ответ №1:

Лучшее решение — не использовать последовательные цифровые клавиши, а полагаться на push-идентификаторы Firebase. Причины, по которым это лучший подход и как они работают, см. В этих классических сообщениях в блоге Firebase:

Если вы настаиваете на использовании массивоподобных ключей, вам придется использовать транзакцию для всего узла закладки, чтобы определить следующий индекс. Это единственный способ предотвратить состояние гонки, с которым вы сейчас сталкиваетесь, когда содержимое массива часто меняется.

Комментарии:

1. Большое вам спасибо @Frank. Ваш ответ мне очень помог!