2016-06-30 5 views
1

これは私のfirebaseを初めて使用したもので、同じクラスに含まれているすべてのメソッドがあります。 nameExistsは、nameに格納されている値がnullでないことをコンソールで確認できる場合でも、常にfalseを返します。 userStatusは、このクラスのDataSnapshotフィールドです。ヘルプFirebaseデータベースがデータを取得していない

答えて

2

ため

public Boolean nameExists(String name){ 
    if (getUserStatus(name) != null){ 
     return true; 
    } else{ return false; } 
} 

public String getUserStatus(String name){ 
    DatabaseReference tmpRef = FirebaseDatabase.getInstance().getReference().child("userStatuses").child(name); 
    ValueEventListener v = new statusesListener(); 
    tmpRef.addValueEventListener(v); 
    tmpRef.removeEventListener(v); 
     return userStatus; 
} 

private class statusesListener implements ValueEventListener{ 

    public void onDataChange(DataSnapshot snap){ 
     userStatus = (String) snap.getValue(); 
    } 
    public void onCancelled(DatabaseError error){ 
    } 

} 

おかげであなたはValueEventListenerコールバックの非同期性を見落としています。リスナーが追加されるとき、通常、値がonDataChange()コールバックによって提供される前にFirebaseサーバーからフェッチされることが必要です。コールバックは、リスナーが追加されてから数ミリ秒後に非同期で発生します。

コードでgetUserStatus()statusesListenerを追加してから削除し、userStatusを返します。そのすべてはonDataChage()が起動する前に発生するため、userStatusの値は変更されません。

また、ValueEventListenerを追加してすぐに削除するのは、典型的な使用例ではなく、リスナーの非同期性を考慮すると、決して起動しない可能性があります。 Query.addListenerForSingleValueEvent()というリスナーを追加することをお勧めします。これは値を一度与えるため、リスナーを削除する必要はありません。

+0

しかし、データを一度しか取得する必要はありません。恐らく、リスナーが追加されるとデータが取得され、値が変更されると再びデータが取得される恐れがあります。 userStatusが更新されるまでに数ミリ秒かかる場合は、userStatus値を使用する前にどれくらい待たなければならないのか、どのようにこの遅延を実装するのか、そしてuserStatusが実際に更新されたことを確認する方法ユーザーはインターネット接続や奇妙なケースを失っただけではありません。また、なぜこのコンセプトはGoogleのFirebaseガイドにもないのですか?この縫い目は重要なメモのように追加して、回避策を提示する必要があります。 –

+0

'addListenerForSingleEvent()'で追加されたリスナーは、一度だけ起動します。これは[1回のデータを読む]セクションの[ドキュメント](https://firebase.google.com/docs/database/android/retrieve-data)に記載されています。遅延や待機に関しては、デザインはイベント駆動型でなければなりません。コードがメイン(UI)スレッドで実行されていると仮定すると、非同期応答を待機するようにブロックすることはできません。 –

+0

次に、取得したデータがいつ取得されたかわからない場合、取得したデータをどのように使用するのですか? –

関連する問題