私はAndroidアプリケーションでFirebaseを使用しています。アプリはグループチャットのようなものを設定し、ユーザーが参加できるようにします。 ユーザーはキーを取得し、対応するDatabaseReferenceに自身を接続できます。 鍵が有効かどうかのチェックが必要です。したがって、グループが作成されると、ホストは自動的にユーザーのリストに自身を追加します。新しいクライアントは、リストにエントリがあるかどうかを確認できます。リストが空の場合、キーは無効です。Firebaseコールバックはテスト中に動作しますが、実行時には動作しません
これは、setValue呼び出しの完了を待つ必要があることを意味します。 Firebaseにはこのことを伝えるコールバックがたくさんありますが、かなり問題があります。場合によっては、単に呼び出されないこともあります。 私は既にこの非決定論的な振る舞いについて質問してきました:How to listen for Firebase setValue completion
これらのコールバックに関する新しい問題を発見しました。 インフラストラクチャを非同期設定に変更しました。すべてのインタラクションはCallableにパッケージ化され、ExecutorServiceに送信されます。結果はFuture <>です。今、私が何かが完了するのを待っていたいならば、私はその未来を待つことができます。未来の中で、Firebaseコールバックを使用する必要があります。
コードは、DBConnectionというラッパークラスにあります。ここで
は、新しいグループ(パーティ)を作成するための私のコードです:
public Future<DBState> createParty() {
// assert entries
assertState(DBState.SignedIn);
// process for state transition
Callable<DBState> creationProcess = new Callable<DBState>() {
@Override
public DBState call() throws Exception {
lock.lock();
try {
// create a new party
ourPartyDatabaseReference = partiesDatabaseReference.push();
usersDatabaseReference = ourPartyDatabaseReference.child("users");
// try every remedy for the missing callbacks
firebaseDatabase.goOnline();
ourPartyDatabaseReference.keepSynced(true);
usersDatabaseReference.keepSynced(true);
// push a value to the users database
// this way the database reference is actually created
// and new users can search for existing users when they connect
// we can only continue after that task has been completed
// add listeners for success and failure and wait for their completion
// TODO: we need information that this task has been finished
// but no callback seems to work
// onSuccess, onCompletion on the task are not reliable
// and the child and value event listeners on the userDatabaseReference are not reliable, too
final CountDownLatch waiter = new CountDownLatch(1);
usersDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
waiter.countDown();
}
@Override
public void onCancelled(DatabaseError databaseError) {
waiter.countDown();
}
});
Task addingTask = usersDatabaseReference.child(user.getUid()).setValue(true);
addingTask.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(Object o) {
waiter.countDown();
}
});
addingTask.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
waiter.countDown();
}
});
try {
waiter.await();
} catch (InterruptedException ex) {
}
connectToParty();
} finally {
lock.unlock();
}
// if we could connect, we are now DBState.Connected,
// otherwise we are still DBState.SignedIn
return state;
}
};
// start process
return executorService.submit(creationProcess);
}
あなたはこのようにそれを使用することができます:私はこれのためにテストを書いた
Future<DBState> creationFuture = dbConnection.createParty();
try {
creationFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
throw new AssertionError("there should be no interrupt");
}catch (TimeoutException ex) {
throw new AssertionError("timeout in party creation");
}catch (ExecutionException ex) {
throw new AssertionError("concurrent execution exception");
}
。 テストでは、すべて正常に動作します。私は今少なくとも12回、canCreateParty
のテストを実行しました。
コールバックが機能することを確認するために、CountDownLatch
を3カウントに増やして、countDowns
にブレークポイントを追加しました。すべてcountDown
に達します。
しかし、実行時にはコールバックが呼び出されません。 ブレークポイントに達しておらず、最終的には将来を待ってタイムアウトします。
私は、エミュレータのすぐ隣にFirebaseコンソールを開いています。私は新しい関係者がどのように作成され、ユーザーが追加されたかを見ることができます。テストと実行時の両方で、パーティーの作成は期待通りに機能し、新しいユーザーが追加されます。 実行時にコールバックが発生しないのはなぜですか?
「ランタイム」には異なるキーストアが含まれていませんか?デバッグ/リリースのように - あなたはSHA1が違うので、私が知っている限り、別のfirebaseキーが必要です。 –
Hm、私は分かりません。私はアンドロイドのsigningReportからFirebaseに自分のデバッグキーを追加しました。そして私はちょうど確認しました:そのレポートはただ一つの鍵を生成します。私が鍵を調べなければならない他の場所はありますか?いずれにしても、キーが拒否された場合、実行時にデータベースに書き込むことができませんでしたか?私は新しいパーティーが作成されていることと、ユーザーが追加されているのを見ることができます。完了のためのコールバックがありません – lhk
うーん、わかりません - あなたがやっていることに全く慣れていない、私はFCMを本当に使っただけです。署名の報告書に1つのSHAが記載されている場合、それは問題ではありません。これは問題が何であるかを知るまで意味をなさない問題の1つです。あなたのテストがどんな方法でも不正にならないことを再度確認し、ファイアベースからの着信メッセージをドロップするだけではないことを確認してください。実際のデバイスから同じ動作をしますか?私はどちらも問題ではないはずだが、それでもなお –