如何收听Firebase的setValue完成情况

时间:2017-10-19 12:21:38

标签: java android database multithreading firebase

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

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

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);

完成此操作后,我调用辅助方法connectToParty来设置一些引用,并将数据库连接的状态更改为DBState.Connected。现在您可以获取聚会的密钥并将其传输给其他用户。使用密钥我的意思是firebase中的名称。

问题是:其他用户需要检查他们是否使用了有效密钥进行连接。他们通过检查key/users下是否有数据来执行此操作。因此,仅当第一个用户已成功写入数据库时​​,该方才有效。

有时写入过程需要很长时间,有时似乎完全失败。所以我设置了听众:

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);
    }
});

测试涵盖了这一点。测试建立连接,登录并创建一个聚会。如果在特定超时内创建了一方,则测试通过。

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

这与超时短暂无关。根本不调用任务的回调。 我读到这个回调仅在你的连接在线时才有效。

所以我在我的代码中添加firebaseDatabase.goOnline();,就在任务之前。但这没有用。

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

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

3 个答案:

答案 0 :(得分:7)

正如offical documentation所说:

  

如果您想知道您的数据何时提交,您可以添加完成侦听器。 setValue()和updateChildren()都将获取一个可选的完成侦听器,该侦听器在写入已提交到数据库时被调用。

这是一个简单的例子:

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.");
        }
    }
});

答案 1 :(得分:5)

对于Kotlin用户,您可以使用此

firebaeRef.setValue("your_value", { error, ref ->
            //setValue operation is done, you'll get null in errror and ref is the path reference for firebase database
        })

此处,firebaeRef是对设置了值的节点/子项的引用,your_value是要设置的值。

答案 2 :(得分:0)

只需将代码放入try catch块中,然后在Toast中查看错误

btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText t=findViewById(R.id.edittext);

              String data=t.getText().toString();

                try {
                    ref.setValue(data);
                    Toast.makeText(MainActivity.this, "Inserted", Toast.LENGTH_SHORT).show();
                }catch (Exception e){
                    Toast.makeText(MainActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
                }
        
            }
        });