如何收听Firebase的setValue完成 [英] How to listen for Firebase setValue completion

查看:169
本文介绍了如何收听Firebase的setValue完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Firebase中设置类似于群聊的内容。
如果您拥有正确的群组ID,则可以加入。



问题是,Firebase参考始终存在。它们是动态创建的。为了在加入过程中允许一些错误检查,我想将创建新数据库条目的用户添加到用户表中。

  public void createParty(){

//你需要登录来创建一个派对
assertState(DBState.SignedIn);

//创建一个新的派对
ourPartyDatabaseReference = partiesDatabaseReference.push();
usersDatabaseReference = ourPartyDatabaseReference.child(users);

//将我们的用户写入用户表,现在ourPartyReference实际上存在
//并且如果您寻找现有用户,您将始终发现至少原始创建者
任务initTask = usersDatabaseReference.child(user.getUid())。setValue(true);

完成此操作后,我调用一个帮助器方法 connectToParty 设置几个引用,并将数据库连接的状态更改为 DBState.Connected 。现在你可以把握党的关键并把它传送给其他用户。带密钥我的意思是在firebase中的名字。

问题是:其他用户需要检查他们是否使用了有效的密钥来连接。他们通过检查 key / users 下是否有数据。所以派对只有在第一个用户成功写入数据库的时候才有效。



有时写入过程需要很长时间,有时看起来完全失败。所以我设置了监听器:
$ b $ pre $ 任务initTask = usersDatabaseReference.child(user.getUid())。setValue(true) ;

initTask.addOnSuccessListener(new OnSuccessListener(){
@Override $ b $ public void onSuccess(Object o){
connectToParty();
}
});

initTask.addOnFailureListener(new OnFailureListener(){
@Override
public void onFailure(@NonNull异常e){
changeState(DBState.SignedIn,DBTransition.Failure );
}
});

这包括在一个测试中。测试建立连接,登录并创建一个聚会。如果派对是在特定的超时时间内创建的,则测试通过。



这10次中有9次没有问题。
但有时测试失败。

这与短暂超时无关。任务的回调根本不被调用。
我读了这个回调只适用于你的连接在线。
$ b $所以我加了 firebaseDatabase.goOnline(); 到我的代码,就在任务之前。但是这并没有帮助。



我通过局域网连接到互联网。所有其他测试都通过了,他们也需要访问firebase。例如,登录过程。

向数据库写入值并等待写入完成的正确方法是什么?

解决方案

官方文档说:


如果您想知道何时数据已经被提交,你可以添加一个完成监听器。 setValue()和updateChildren()都带有一个可选的完成监听器,当写入已经提交给数据库时,这个监听器被调用。

是一个简单的例子:

  ref.setValue(我在写数据到Firebase数据库,新的Firebase.CompletionListener ){
@Override
public void onComplete(FirebaseError firebaseError,Firebase firebase){
if(firebaseError!= null){
System.out.println(Data could not be保存。+ firebaseError.getMessage());
} else {
System.out.println(Data saved successfully。);
}
}
});


I would like to set up something like a groupchat in Firebase. If you have the correct group ID, you can join.

The problem is that Firebase references always exist. They are created dynamically. To allow some error checking in the joining process, I want to add the user who created the new database entry to a table of users.

public void createParty() {

    // you need to be signed in to create a party
    assertState(DBState.SignedIn);

    // create a new party
    ourPartyDatabaseReference = partiesDatabaseReference.push();
    usersDatabaseReference = ourPartyDatabaseReference.child("users");

    // write our user to the table of users, now the ourPartyReference actually exists
    // and if you look for existing users, you will always find at least the original creator
    Task initTask = usersDatabaseReference.child(user.getUid()).setValue(true);

After this has been done, I call a helper method connectToParty to set up a few references and change the state of the database connection to DBState.Connected. Now you can take the key of the party and transmit it to other users. With key I mean the name in firebase.

The problem is: Other users need to check whether they used a valid key to connect. They do this by checking if there is data under key/users. So the party is only valid if the first user has been successfully written to the database.

Sometimes the write process takes very long, sometimes it seems to fail completely. So I've set up listeners:

Task initTask = usersDatabaseReference.child(user.getUid()).setValue(true);

initTask.addOnSuccessListener(new OnSuccessListener() {
    @Override
    public void onSuccess(Object o) {
        connectToParty();
    }
});

initTask.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        changeState(DBState.SignedIn, DBTransition.Failure);
    }
});

This is covered by a test. The test sets up a connection, signs in and creates a party. If the party is created within a specific timeout, the test passes.

9 out of 10 times this works without a problem. But sometimes the test fails.

This has nothing to do with the timeout being to short. The callbacks from the task are simply not called. I read that this callback only works if your connection is online.

So I added firebaseDatabase.goOnline(); to my code, just before the task. But that doesn't help.

I'm connected to the internet over LAN. All the other tests pass, and they need to access firebase, too. For example for the sign-in process.

What is the correct way to write a value to the database and wait for the write to complete ?

解决方案

As the offical documentation says:

If you'd like to know when your data has been committed, you can add a completion listener. Both setValue() and updateChildren() take an optional completion listener that is called when the write has been committed to the database.

This is a simple example:

ref.setValue("I'm writing data to a Firebase database", new Firebase.CompletionListener() {
    @Override
    public void onComplete(FirebaseError firebaseError, Firebase firebase) {
        if (firebaseError != null) {
            System.out.println("Data could not be saved. " + firebaseError.getMessage());
        } else {
            System.out.println("Data saved successfully.");
        }
    }
});

这篇关于如何收听Firebase的setValue完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆