【问题标题】:How to wait until firebase save all data?如何等到firebase保存所有数据?
【发布时间】:2018-03-13 14:08:26
【问题描述】:

我需要一些有关异步任务和 Firebase 的帮助。我需要在 Firebase 实时数据库中保存 n 个元素,但我不知道如何处理回调。

这是我的代码:

 TagRepository tagRepository = new TagRepository();
    for (Tag tag : databaseTags){
        if (user.getTags().containsKey(tag.getId())){
            Completable completable = tagRepository.saveUserOnTag(String.valueOf(tag.getId()), user.getUid());
        }else{
            tagRepository.removeUserOnTag(String.valueOf(tag.getId()), user.getUid());
        }
    }

  public Completable saveUserOnTag(String idTag, String userUid) {
    return io.reactivex.Completable.create(emitter->{
        reference.child(idTag).child("users/").child(userUid).setValue(true).addOnCompleteListener(task -> emitter.onComplete());
    });
}

如果我在这个方法上使用回调,回调将被调用 n 次,所以我不知道如何知道它们何时都已保存,以便继续。

正如您在方法上看到的那样,我正在尝试使用 Completable 进行一些操作,但我真的不知道如何处理它。有什么简单的方法可以同时保存所有数据或控制所有正在保存的数据?

【问题讨论】:

  • 你可以先收集你所有的物品并将它们保存在一个更新中,就像它显示的in the docs

标签: android firebase firebase-realtime-database rx-java2 rx-android


【解决方案1】:

根据官方documentation,可以使用同步更新。

使用这些路径,您可以通过一次调用 updateChildren() 来同时更新 JSON 树中的多个位置。以这种方式进行的同时更新是原子的:要么所有更新都成功,要么所有更新都失败。

【讨论】:

  • 非常感谢,我在谷歌上到处搜索,但没有检查官方文档,真丢脸
  • 我明白了。干杯!
【解决方案2】:

您可以尝试使用 Tasks.await 同步更新 firebase 数据

saveUserOnTag方法改成如下试试

public Completable saveUserOnTag (String idTag, String userUid){
        return io.reactivex.Completable.create(emitter -> {
            Tasks.await(reference.child(idTag).child("users/").child(userUid).setValue(true));
            emitter.onComplete();
        });

【讨论】:

  • 但是使用这段代码,我怎么知道所有值什么时候更新?
  • 它会阻塞一个任务并同步获取结果。这意味着它成功时将进入下一行。当您的程序已经在后台线程中执行时,这很有用。确保 Tasks.await 您不是从 Android 主线程执行的。详情:developers.google.com/android/guides/tasks#blocking
  • 哦,这个其实挺好的,谢谢你的解释
【解决方案3】:

抱歉,我不知道 Rx,但这是一种在一次 API 调用中插入所有数据的方法。 onComplete() 方法是更新完成回调。

Map<String, Object> values = new HashMap<>();
for (Tag tag : databaseTags){
    if (user.getTags().containsKey(tag.getId())){
        values.put(idTag + "/users/" + userUid, true);
    }else{
        tagRepository.removeUserOnTag(String.valueOf(tag.getId()), user.getUid());
    }
}

reference.updateChildren(values, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        // all data saved, do next action
    }
});

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2019-06-04
    • 1970-01-01
    • 2020-12-18
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多