所以我浏览了有关如何检索数据Firebase的文档:https://firebase.google.com/docs/database/android/retrieve-data
在我的firebase应用程序中,我使用addListenerForSingleValueEvent检索值。 在onDataChange方法中检索的那些值(此处为 userIdKey )用于更新数据库中的其他某些位置。
我观察到的是,有时除了以外的地方都会进行更新 123 (请参阅下面的代码)。
DatabaseReference channelFollowersRef = mDatabase.child("followers").child(mKey);
channelFollowersRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot childSnapshot:dataSnapshot.getChildren()){
String userIdKey=childSnapshot.getKey();
/*123*/ delChannelMap.put("/user-subscriptions/" + userIdKey + "//" + mChannelKey,null);
}
delChannelMap.put("/channels/" + mChannelKey, null);
delChannelMap.put("/user-channels/" + getUid() + "/" + mChannelKey, null);
delChannelMap.put("/channels-notices/" + mChannelKey, null);
delChannelMap.put("/channels-subChannels/" + mChannelKey, null);
delChannelMap.put("/channels-subChannels-comments/" + mChannelKey, null);
delChannelMap.put("/channel-followers/" + mChannelKey, null);
mDatabase.updateChildren(delChannelMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
Toast.makeText(ChannelDetailActivity.this, "Channel is now deleted.", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
如何解决这个问题。
也有人可以详细说明onDataChange如何工作,当检索到节点上的所有值或检索到“某些”数据时,是否会调用它?
在检索数据时,应该在这种情况下使用AsyncTask。
答案 0 :(得分:2)
onDataChange
一次为您提供所有基础子节点。
Firebase在检索数据时使用不同的线程来执行其任务,因此无需使用AsyncTask
。
您的代码中的问题可能是由于String userIdKey=childSnapshot.getKey();
... childSnapshot.getKey();
没有触发您想要的数据..如果数据被正确检索,您应该检查LOGCAT。
如果还不清楚,请添加数据库的Json Data,以便更容易理解正在发生的事情。
答案 1 :(得分:1)
您的代码似乎删除了许多位置的扇出数据。
执行此类多位置update()
时,将在进行任何更改之前检查所有节点的安全规则。因此(除非Firebase执行这些特定安全规则的方式存在错误),安全规则不会导致断开连接。
如果您的其他节点已更新,但未删除/user-subscriptions/" + userIdKey + "//" + mChannelKey
,则您可能无法在dataSnapshot
中收到任何子节点(因此未在delChannelMap
中传递它们)。您需要在调试器中运行代码来验证。
每当解决此类问题时,请务必处理onCancelled()
。这是了解操作失败原因的最简单方法。虽然我不认为它会在这里执行(毕竟,写操作似乎成功了),我建议你attach a completion callback to setValue
:
ref.setValue("My new value", new DatabaseReference.CompletionListener() {
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
throw databaseError.toException();
}
});
抛出这样的异常可以确保下次很难忽略这样的错误。