我写这个问题是因为我在不同情况下检索空值或数据。让我解释一下:
- 图形解释 -
我正在开发一款应用程序来帮助可以创建聊天并列出现有聊天的动物:
将要存储在lastMessage部分的聊天消息(此处,我只存储来自两个用户的最后一条消息,覆盖最后一条消息)和allMessages部分(此处,我存储来自两个用户的所有消息)< / p>
- 问题 -
所以,当接收者访问存储在Firebase中的所有先前数据的聊天时和我的应用询问是否存在聊天(创建或不创建,因为他/她可能是另一个发件人谁想要创建另一个聊天),如果创建了聊天状态, Firebase正在检索空。
我不知道自己做错了什么,因为 chatList可以通过使用lastMessage的发送者/接收者来访问数据以列出现有的聊天(聊天 - &gt; lastMessages ),但如果我需要访问:
,我会遇到问题- 我的尝试 -
现在,我将使用addValueEventListener显示 chatList 中最重要的部分(它正在工作)
private FirebaseAuth.AuthStateListener mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
mUser = firebaseAuth.getCurrentUser();
if (mUser != null) {
// User is signed in
Log.d("FIREBASE_AUTH", "onAuthStateChanged:signed_in:" + mUser.getUid());
} else {
// User is signed out
Log.d("FIREBASE_AUTH", "onAuthStateChanged:signed_out");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chatlist);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
mAuth = FirebaseAuth.getInstance();
mUser = mAuth.getCurrentUser();
setLastChatMessage();
}
@Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
@Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
private void setLastChatMessage() {
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mDatabaseReference.child("chats").child("lastMessages").child(mUser.getUid())
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot animalsDataSnapshot) {
if (animalsDataSnapshot.getValue() != null) {
for (DataSnapshot animalDataSnapshot : animalsDataSnapshot.getChildren()) {
for (DataSnapshot homeSnapshot : animalDataSnapshot.getChildren()) {
//GETTING THE DATA TO QUERY AGAIN WITH addListenerForSingleValueEvent, LIST THE EXISTING CHATS AND SET INTENTS TO CHAT
}
}
}
mDatabaseReference.removeEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("databaseError", String.valueOf(databaseError));
}
});
}
在这里,我将使用addListenerForSingleValueEvent和addValueEventListener(它不能正常工作)来显示聊天中最重要的部分
private FirebaseAuth.AuthStateListener mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
mUser = firebaseAuth.getCurrentUser();
if (mUser != null) {
// User is signed in
Log.d("FIREBASE_AUTH", "onAuthStateChanged:signed_in:" + mUser.getUid());
} else {
// User is signed out
finish();
Log.d("FIREBASE_AUTH", "onAuthStateChanged:signed_out");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarChat);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
// Initialize Firebase Auth
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
setChat();
}
private void setChat() {
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mDatabaseReference.child("chats").child("allMessages").child(animalUid).child(homeUid)
.orderByKey().equalTo("-0valueByDefect")
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.getValue() == null) {
// IF THERE IS NOT A CHAT, CREATE A NEW ONE
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("databaseError", String.valueOf(databaseError));
}
});
mDatabaseReference.child("chatStatus").child(animalUid).child(homeUid)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(mFirebaseAuth.getCurrentUser().getUid())
.child("unreadMessages").getValue() == null) {
// IF MY STATUS IS NOT CREATED, ADD IT
}
mDatabaseReference.removeEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("databaseError", String.valueOf(databaseError));
}
});
}
@Override
public void onStart() {
super.onStart();
mFirebaseAuth.addAuthStateListener(authListener);
connectMyUser(true);
}
@Override
public void onStop() {
super.onStop();
connectMyUser(false);
if (authListener != null) {
mFirebaseAuth.removeAuthStateListener(authListener);
}
}
private void connectMyUser(boolean isConnected) {
String myUserUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
Map<String, Object> childUpdates = new HashMap<>();
if (isConnected) {
childUpdates.put("/chatStatus/" + animalUid + "/" + homeUid
+ "/" + myUserUid + "/state", "connected");
childUpdates.put("/chatStatus/" + animalUid + "/" + homeUid
+ "/" + myUserUid + "/unreadMessages", 0);
} else {
childUpdates.put("/chatStatus/" + animalUid + "/" + homeUid
+ "/" + myUserUid + "/state", "disconnected");
}
mDatabaseReference.updateChildren(childUpdates);
}
- 我的方法 -
我有一周以来遇到过这些问题,但昨天我发现错误的方式使其正常工作。在 chatList 上我写了与聊天相同的查询,因此我得到了相同的结果,但是当用户访问聊天时,应用再次询问该聊天是否存在以及用户是否有状态,我获取数据。
我有一些问题:
您认为它是否是指数问题?这就是我所拥有的
{ &#34;规则&#34;:{ &#34; .read&#34;:&#34; auth!= null&#34;, &#34; .write&#34;:&#34; auth!= null&#34;, &#34; chatStatus&#34;:{ &#34; .indexOn&#34;:&#34; .value&#34; }, &#34;聊天&#34;:{ &#34; .indexOn&#34;:&#34; .value&#34; } } }
也许我没有正确使用removeEventListener?
我应该使用addChildEventListener而不是addValueEventListener吗?我尝试过,但结果相同
你能解释一下我误解了什么吗?
- 更新18/09/2017 -
嗨,我想我找到了解决问题的正确方法:I used keepSynced并且Firebase文档说:
Firebase实时数据库客户端会自动在这些位置下载数据,即使引用没有活动的侦听器也会保持同步。
这就是它工作的原因,但是我仍然不明白为什么我需要使用keepSynced属性,因为其余的节点都没有需要它(也许听众不活跃?)和当我需要将keepSynced更改为false 如果我需要firebase监听该节点。
我仍然想知道这是否是指数问题。
提前致谢!!