如何在Firebase Realtime数据库中的嵌套回调期间处理错误?

时间:2019-06-17 11:37:23

标签: java android firebase firebase-realtime-database

我正在使用Firebase实时数据库,并且需要在数据库中执行多项操作,其中一些操作取决于上一个的结果,从而创建了著名的“回调地狱”。例如,当第二个呼叫出错但第一个呼叫成功时,我该如何处理错误?

我试图找到一些“ 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 :(得分:0)

如果要在一次调用中更新数据库中的多个值,请使用André在其注释中提到的多位置更新。

通过多位置更新,您的整个代码可以简化为:

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")
  • 如果您需要根据节点的现有值编写新值,则需要使用事务。但是请注意,跨多个顶级节点的事务往往会引起高度争议,因此,我建议您在当前用例中尽量避免此类事务。