Как обрабатывать ошибки во время вложенных обратных вызовов в базе данных Firebase Realtime? - PullRequest
1 голос
/ 17 июня 2019

Я использую базу данных Firebase Realtime, и мне нужно выполнить несколько операций в базе данных, некоторые из которых зависят от результата предыдущего, создавая знаменитый «ад обратного вызова». Как я могу обработать ошибки, когда, например, второй вызов идет не так, как первый, но успешно?

Я пытался найти «транзакцию базы данных Firebase в реальном времени» (например, транзакции в mysql или postgres), но не нашел хороших примеров.

mDb.getReference("users").setValue("someValue").addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {

            if(task.isSuccessful()){

              mDb.getReference("services").setValue("someValue2").addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {

                        if(task.isSuccessful()){

                            mDb.getReference("stores").setValue("someValue3").addOnCompleteListener(new OnCompleteListener<Void>() {
                                @Override
                                public void onComplete(@NonNull Task<Void> task) {

                                    // Here, for some reason, the value "someValue3" could not be set.     
                                }
                            });
                        }
                    }
                });
            }
        }
    });

Мне нужно, чтобы, если какая-то операция пошла не так, чтобы вернуть («откатить») значения, установленные ранее. Прямо сейчас, если транзакция со ссылкой «хранилища» завершится неудачно, значения, заданные для «пользователей» и «служб», останутся в базе данных.

1 Ответ

0 голосов
/ 17 июня 2019

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

При обновлении с несколькими местоположениями весь ваш код может быть уменьшен до:

Map<String, Object> values = new HashMap<>();
values.put("users", "someValue");
values.put("services", "someValue2");
values.put("stores", "someValue3");
mDb.updateChildren(values).addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        // All writes either completed, or none happened
    }
});

Некоторые примечания:

  • Ключи на карте values могут содержать целые пути, поэтому если вы хотите обновить имя конкретного пользователя, это может бытьvalues.put("users/uidOfTheUser/name", "new name").
  • Если вам нужно написать новое значение на основе существующего значения узла, вам нужно будет вместо этого использовать транзакции.Но обратите внимание, что транзакции между несколькими узлами верхнего уровня имеют тенденцию быть очень спорными, поэтому я бы рекомендовал стараться держаться подальше от них в вашем текущем сценарии использования.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...