2017-10-19 7 views
0

Firebaseでグループチャットのようなものを設定したいと思います。 グループIDが正しい場合は、参加できます。Firebase setValueの完了を聞く方法

問題は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); 

は、私はいくつかの参照を設定し、DBState.Connectedへのデータベース接続の状態を変更するためのヘルパーメソッドconnectToPartyを呼び出します。今、あなたはパーティーの鍵を受け取り、それを他のユーザーに送信することができます。キーで、私は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); 
    } 
}); 

これはテストによってカバーされています。テストは接続を確立し、ログインしてパーティを作成します。パーティが特定のタイムアウト時間内に作成された場合、テストは合格になります。

9回のうち9回は問題なく動作します。 しかし、テストが失敗することがあります。

これは、タイムアウトが短くなることとは関係ありません。タスクからのコールバックは単に呼び出されません。 このコールバックは、接続がオンラインの場合にのみ機能することを読んでいます。

私は自分のコードにタスクの直前にfirebaseDatabase.goOnline();を追加しました。しかし、それは役に立たない。

私はLAN経由でインターネットに接続しています。他のすべてのテストは合格し、ファイアベースにもアクセスする必要があります。たとえば、サインインプロセスです。

データベースに値を書き込み、書き込みが完了するのを待つ正しい方法は何ですか? offical documentationとして

+0

? –

+0

タイムアウトです。私はコールバックのために10秒待っています、そして、テストは失敗します。 – lhk

+0

この2つのどちらも呼び出されない – lhk

答えて

1

は言う:

あなたのデータがコミットされたときに知りたい場合は、あなたが完了リスナーを追加することができます。 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."); 
     } 
    } 
}); 
+0

これは実際に私が最初に試したことです。同じ問題。 – lhk

+0

'setPersistenceEnabled(true);'を使ってみましたか?つまり、データベースのデータをメモリとディスクの2つの場所に保存することができます。 'keepSynced(true)'を使うこともできます。これは、アプリケーション内のデータが(ネットワークに接続されている限り)サーバ上のデータベースの内容と常に最新の状態になることを意味します。 –

+1

私は2つを試しました。問題はもはや発生しませんでした。新しいコードを削除しましたが、問題は発生しなくなりました。この非決定的な振る舞いをデバッグすることは非常に難しいです。 – lhk

関連する問題