我正在使用 Firebase 实时数据库,需要在数据库中执行多个操作,其中一些操作取决于前一个操作的结果,从而创建了著名的“回调 hell ”。例如,当第二次调用出错但第一次调用成功时,我该如何处理错误?
我试图找到一些“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.
}
});
}
}
});
}
}
});
如果某些操作出错,我需要恢复(“回滚”)之前设置的值。现在,如果引用“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
}
});
一些注意事项:
values
映射中的键可以包含整个路径,因此如果您想要更新特定用户的名称,可以使用values.put("users/uidOfTheUser/name", "new name")
。- 如果您需要根据节点的现有值写入新值,则需要使用事务。但请注意,跨多个顶级节点的交易往往会引起很大争议,因此我建议您在当前的用例中尽量远离它们。
关于java - 如何处理 Firebase 实时数据库中嵌套回调期间的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56630527/