Java 如何处理Firebase实时数据库中嵌套回调期间的错误?

Java 如何处理Firebase实时数据库中嵌套回调期间的错误?,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我正在使用Firebase实时数据库,我需要在数据库中执行多个操作,其中一些操作取决于前一个操作的结果,创建著名的“回调地狱”。例如,当第二次调用出错,但第一次调用成功时,如何处理错误 我试图找到一些“Firebase实时数据库事务”(如mysql或postgres中的事务),但没有找到任何好的示例 mDb.getReference("users").setValue("someValue").addOnCompleteListener(new OnCompleteListener<Voi

我正在使用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.     
                                }
                            });
                        }
                    }
                });
            }
        }
    });
mDb.getReference(“用户”).setValue(“someValue”).addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
mDb.getReference(“服务”).setValue(“someValue2”).addOnCompleteListener(新的OnCompleteListener()){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
mDb.getReference(“stores”).setValue(“someValue3”).addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
//在这里,由于某种原因,无法设置值“someValue3”。
}
});
}
}
});
}
}
});

如果某个操作出错,我需要将之前设置的值还原(“回滚”)。现在,如果引用“stores”上的事务失败,“users”和“services”上设置的值将保留在数据库中。

如果您想在一次调用中更新数据库中的多个值,请使用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
    }
});
Map values=newhashmap();
value.put(“用户”、“someValue”);
价值。出售(“服务”、“某些价值2”);
价值。出售(“存储”、“某些价值3”);
updateChildren(values).addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
//所有写入操作要么已完成,要么未发生任何写入操作
}
});
一些注意事项:

  • values
    映射中的键可以包含整个路径,因此如果要更新特定用户的名称,可以使用
    values.put(“users/uidOfTheUser/name”,“new name”)
  • 如果需要基于节点的现有值写入新值,则需要使用事务。但请注意,跨多个顶级节点的事务往往具有高度争议性,因此我建议您在当前用例中尽量远离它们

如果您想在一次调用中更新数据库中的多个值,请使用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
    }
});
Map values=newhashmap();
value.put(“用户”、“someValue”);
价值。出售(“服务”、“某些价值2”);
价值。出售(“存储”、“某些价值3”);
updateChildren(values).addOnCompleteListener(新的OnCompleteListener(){
@凌驾
未完成的公共void(@NonNull任务){
//所有写入操作要么已完成,要么未发生任何写入操作
}
});
一些注意事项:

  • values
    映射中的键可以包含整个路径,因此如果要更新特定用户的名称,可以使用
    values.put(“users/uidOfTheUser/name”,“new name”)
  • 如果需要基于节点的现有值写入新值,则需要使用事务。但请注意,跨多个顶级节点的事务往往具有高度争议性,因此我建议您在当前用例中尽量远离它们

我认为您要查找的正确搜索词是。我认为您要查找的正确搜索词是。