如何等到 firebase 保存所有数据?

How to wait until firebase save all data?

我在异步任务和 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 进行一些操作,但我真的不知道如何处理它。有什么简单的方法可以同时保存所有数据或控制所有正在保存的数据??

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

Using those paths, you can perform simultaneous updates to multiple locations in the JSON tree with a single call to updateChildren(). Simultaneous updates made this way are atomic: either all updates succeed or all updates fail.

抱歉,我不知道 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
    }
});

希望对您有所帮助:)

您可以尝试使用 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();
        });