我目前正在尝试编写一个消息传递应用程序,并发现了一个我已经被困了两个星期的错误,而且无法到达任何地方。
该应用程序的工作原理如下: 联系用户时,应将两个用户的状态设置为“已阻止”,以便其他任何人都无法联系他们。这就是我在程序中实现它的方式:
发送按钮:
openNewChatButton = (Button) findViewById(R.id.mainSendButton);
openNewChatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String checkText = sendMainMessage.getText().toString();
if (checkText.isEmpty()) {
Toast.makeText(MainActivity.this, "Bitte verfasse vorher eine Nachricht.", Toast.LENGTH_SHORT).show();
} else {
sendMessageToUser();
}
}
});
创建消息并发送消息:
public void sendMessageToUser() {
mUsersDatabaseForRandomChatUser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
key = sampleUserID;
if (current_uid.equals(key) || key == null || key == "") {
Toast.makeText(MainActivity.this, "Keinen passenden Chatpartner gefunden!", Toast.LENGTH_SHORT).show();
} else {
Intent newMessageIntent = new Intent(MainActivity.this, ChatActivity.class);
newMessageIntent.putExtra("chatuser_id", key);
newMessageIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
newMessageIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
sendChatMessage();
finish();
setYouChatID();
changeStateOfUserToBlocked();
startActivity(newMessageIntent);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void sendChatMessage() {
String message = sendMainMessage.getText().toString();
if (!TextUtils.isEmpty(message)) {
String current_user_ref = "messages/" + current_uid + "/" + key;
String chat_user_ref = "messages/" + key + "/" + current_uid;
DatabaseReference user_message_push = mRootReference.child("Messages").child(current_uid).child(key).push();
String push_id = user_message_push.getKey();
Map messageMap = new HashMap();
messageMap.put("message", message);
messageMap.put("seen", false);
messageMap.put("type", "text");
messageMap.put("time", ServerValue.TIMESTAMP);
messageMap.put("from", current_uid);
sendMainMessage.setText("");
Map messageUserMap = new HashMap();
messageUserMap.put(current_user_ref + "/" + push_id, messageMap);
messageUserMap.put(chat_user_ref + "/" + push_id, messageMap);
mRootReference.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null)
Log.d("CHAT_LOG", databaseError.getMessage().toString());
}
});
}
}
更改用户状态并设置当前聊天伙伴:
private void setYouChatID() {
DatabaseReference youChatID = mRootReference.child("Users").child(mAuth.getCurrentUser().getUid()).child("youchatid");
youChatID.setValue(key);
DatabaseReference youChatIDChatUser = mRootReference.child("Users").child(key).child("youchatid");
youChatIDChatUser.setValue(current_uid);
}
private void changeStateOfUserToBlocked() {
DatabaseReference stateDatabaseChatUser = mRootReference.child("Users").child(key).child("status");
stateDatabaseChatUser.setValue("blocked");
DatabaseReference stateDatabaseUser = mRootReference.child("Users").child(mAuth.getCurrentUser().getUid()).child("status");
stateDatabaseUser.setValue("blocked");
}
到此为止,一切都很完美。
现在,当聊天关闭时,两个用户的状态应该设置为“free”,并且当前的chatPartner(youchatid)应该设置为“default”。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAuth = FirebaseAuth.getInstance();
mCurrentUserId = mAuth.getCurrentUser().getUid();
mRootReference = FirebaseDatabase.getInstance().getReference();
mChatUserId = getIntent().getStringExtra("giveUserChatID");
setContentView(R.layout.activity_securty_pop_up);
bestaetigenButton = findViewById(R.id.bestaetigenButton);
bestaetigenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecurtyPopUpActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
finish();
startActivity(intent);
changeStateOfUserToFree();
removeYouChatID();
}
});
}
public void changeStateOfUserToFree() {
DatabaseReference stateDatabaseChatUser = mRootReference.child("Users").child(mChatUserId).child("status");
stateDatabaseChatUser.setValue("free");
DatabaseReference stateDatabaseUser = mRootReference.child("Users").child(mAuth.getCurrentUser().getUid()).child("status");
stateDatabaseUser.setValue("free");
}
public void removeYouChatID() {
DatabaseReference youChatID = mRootReference.child("Users").child(mAuth.getCurrentUser().getUid()).child("youchatid");
youChatID.setValue("default");
DatabaseReference youChatIDChatUser = mRootReference.child("Users").child(mChatUserId).child("youchatid");
youChatIDChatUser.setValue("default");
}
这正是问题的开始!
此时程序似乎陷入了循环中。 两个属性都会短暂更改,但会返回旧值并再次打开活动。
但是,如果我关闭智能手机上的所有任务(包括我的应用程序)并再次尝试相同的操作,它可以正常工作。 然而,在第一次之后,它不再起作用并且循环重新开始,正如您从视频中看到的那样。
因为这不容易理解,我在这里添加了一个视频: https://www.youtube.com/watch?v=fNgjYbgB44w
我不仅仅是绝望而且无法找到解决这个问题的方法?也许你们其中一个人会有一个想法。
答案 0 :(得分:6)
我无法相信解决方案是如此“简单”。我一直认为setYouChatID()
方法中的ValueEventListeners是错误的。但是,在sendMessageToUser()
方法中,仍有addValueEventListener()
而不是addListenerForSingleValueEvent()
。我解决了这个问题后,问题就消失了!
答案 1 :(得分:1)
如果要在dataChange方法中执行任何数据库修改或任何函数,请始终使用addListenerForSingleValueEvent()