Android Firebase数据库路径非法异常求助(含代码与日志)
嘿,我看了你遇到的Firebase数据库路径错误问题,咱们来一步步把它解决掉!
问题根源
从你的Logcat日志里一眼就能找到问题:
com.google.firebase.database.DatabaseException: 无效的Firebase数据库路径: https://rescuex-8f9c9.firebaseio.com/Users/NcZ0McVHEuRfaMv39gHbDlpjI1X2。Firebase数据库路径不得包含'.'、'#'、'$'、'['或']'
你把完整的Firebase数据库引用URL当成了节点名称来用,而Firebase的路径节点绝对不能包含https://、.这类特殊字符。
看代码里的这行:
mChatUser = user_id.getRef().toString();
user_id已经是指向Users/当前用户ID的DatabaseReference对象,调用toString()会返回这个引用的完整URL字符串,而不是你需要的用户ID本身。之后你在addEmergencyChat()和addEmergencyMessage()里用这个mChatUser作为路径节点,自然就触发了非法字符的异常。
解决方案
你需要把mChatUser改成合法的节点名称,也就是目标用户的ID(或者你想要存储的节点名称),而不是完整的URL。
步骤1:修正mChatUser的赋值逻辑
如果你的需求是给某个特定用户发送紧急消息,那你需要先获取这个目标用户的ID——比如从之前的页面通过Intent传递过来:
// 假设从上个页面跳转时,传递了目标用户ID的Extra mChatUser = getIntent().getStringExtra("target_user_id");
如果只是想记录当前用户的紧急求助信息,那你甚至可以去掉mChatUser,或者把它设置成一个固定的合法节点名(比如"Emergency_Requests")。
步骤2:修复addEmergencyChat()中的路径
把所有用到mChatUser的地方,替换成正确的用户ID(或合法节点名)。比如如果是发给管理员,你可以预先定义管理员的用户ID:
private void addEmergencyChat() { locationTrack = new LocationTrack(MenuActivity.this); if (locationTrack.canGetLocation()) { double longitude = locationTrack.getLongitude(); double latitude = locationTrack.getLatitude(); // 替换成目标用户的ID,比如管理员ID String targetUserId = "你的管理员用户ID"; String current_user_ref = "Emergency_Messages/" + mCurrentUserId + "/" + targetUserId; String chat_user_ref = "Emergency_Messages/" + targetUserId + "/" + mCurrentUserId; DatabaseReference chat_push_key = mRootRef.child("Emergency_Messages").child(mCurrentUserId).child(targetUserId).push(); String push_key = chat_push_key.getKey(); Map messageMap = new HashMap(); messageMap.put("userName", userName); messageMap.put("latitude", latitude); messageMap.put("longitude", longitude); messageMap.put("from", mCurrentUserId); messageMap.put("seen", false); messageMap.put("time", ServerValue.TIMESTAMP); Map messageUserMap = new HashMap(); messageUserMap.put(current_user_ref + "/" + push_key, messageMap); messageUserMap.put(chat_user_ref + "/" + push_key, messageMap); mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { if(databaseError != null){ Log.d("TAG", databaseError.getMessage().toString()); } } }); } else { locationTrack.showSettingsAlert(); } }
步骤3:同步修复addEmergencyMessage()
同样,addEmergencyMessage()里也用到了mChatUser,你需要把它替换成正确的用户ID,避免触发同样的错误:
private void addEmergencyMessage() { // 替换成目标用户ID String targetUserId = "你的目标用户ID"; mRootRef.child("Emergency_Chat").child(mCurrentUserId).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { if(!dataSnapshot.hasChild(targetUserId)){ Map chatAddMap = new HashMap(); chatAddMap.put("seen",false); chatAddMap.put("timestamp", ServerValue.TIMESTAMP); Map chatUserMap = new HashMap(); chatUserMap.put("Emergency_Chat/"+mCurrentUserId+"/"+targetUserId, chatAddMap); chatUserMap.put("Emergency_Chat/"+targetUserId+"/"+mCurrentUserId, chatAddMap); mRootRef.updateChildren(chatUserMap, new DatabaseReference.CompletionListener() { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { if(databaseError!= null){ Toast.makeText(MenuActivity.this, "Error: "+databaseError.getMessage(), Toast.LENGTH_SHORT).show(); } } }); } } @Override public void onCancelled(DatabaseError databaseError) { } }); }
总结
核心问题就是你误把DatabaseReference的完整URL当成了节点名称,Firebase的路径节点只能是不含特殊字符的简单字符串。只要把mChatUser替换成合法的用户ID(或节点名),这个异常就能解决啦!
内容的提问来源于stack exchange,提问作者Malusi Gcabashe

