【问题标题】:DataSnapshot not working to create custom objectsDataSnapshot 无法创建自定义对象
【发布时间】:2020-06-10 17:20:01
【问题描述】:

我的问题是我正在尝试让 messageAdapter 在 MessageActvity 的 recycleView 上显示数据库中的消息,这是执行此操作的方法代码(简而言之):

案例 1

private void readMessages(final String myID, final String userID, final String imageURL) {
    mChat = new ArrayList<>();

    reference = FirebaseDatabase.getInstance().getReference("Chats");
    reference.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            mChat.clear();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Chat chat = snapshot.getValue(Chat.class);

                assert chat != null;
                if ( chat.getSender().equals(myID) &&  chat.getReceiver().equals(userID) ||
                     chat.getSender().equals(userID) &&  chat.getReceiver().equals(myID)) {
                    mChat.add(chat) ;
                }

                messageAdapter = new MessageAdapter(MessageActivity.this, mChat, imageURL);
                recyclerView.setAdapter(messageAdapter);
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }

    });
}

错误:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.String.equals(java.lang.Object)”

问题是当手动定义聊天聊天时,该方法运行良好:

案例 2

Chat chat = new Chat(sender, receiver, "hi there");

它甚至显示消息“你好”X 次(X = 数据库中的消息数)。

我什至尝试做类似的事情来使用快照:

案例 3

 String sender = snapshot.child("sender").getValue()).toString();
 String receiver = snapshot.child("receiver").getValue()).toString();
 String message = snapshot.child("message").getValue()).toString();
            Chat chat = new Chat(sender,receiver,message);

但是,它仍然不起作用。结果总是崩溃(除了手动定义的case-2,都可以)。

我尝试将 if 语句的条件更改为:

案例4

if (chat.getSender() != null && chat.getReceiver() != null && chat.getSender().equals(myID) &&  chat.getReceiver().equals(userID) ||
    chat.getSender() != null && chat.getReceiver() != null && chat.getSender().equals(userID) &&  chat.getReceiver().equals(myID)) {
                    mChat.add(chat) ;
    }

在这样做之后,应用程序不再崩溃,因为 if 语句不起作用......我认为让应用程序崩溃的是

chat.getSender() == null && chat.getReceiver == null

当 if 语句开始检查它所破坏的条件时。

EDIT-updated: 在尝试了 log.v 之后,结果发现从 datasnapshot 和 getter 方法返回的值是 null!。这是代码

if (chat.getSender() == null){
         Log.v("MessageActivity", "sender is null: " + chat.getSender());
}
if (chat.getReceiver() == null) {
         Log.v("MessageActivity", "receiver is null: " + chat.getReceiver());
}

更新

Log.v("MessageActivity", "snapshot: " +snapshot );
Log.v("MessageActivity", "chat variables: " + chat.getMessage() + ", " + chat.getReceiver() + ", " + chat.getSender() );
Log.v("MessageActivity", "mchat: " + mChat);

控制台:

2020-06-10 21:17:44.578 29735-29735/com.example.android.chattingapp V/MessageActivity: sender is null: null
2020-06-10 21:17:44.578 29735-29735/com.example.android.chattingapp V/MessageActivity: receiver is null: null

//updated
snapshot: DataSnapshot { key = -M9TzQuBbYfv-OhJgRyR, value = {message: =hahah, sender: =DuD8LfwlreNjByrptsh4zgXDQie2, receiver: =hFpPOfnvsKbJiZtfCBoGyDPnQXy2} }
chat variables: null, null, null
mchat: []

在尝试调试代码时,快照似乎具有此图像The debug screen 中显示的数据。

Edit-2:我为firebase数据库数据Database data添加了一张图片

Edit-3:我的聊天类

public class Chat{

private String sender;
private String receiver;
private String message;

public Chat(String message, String sender, String receiver) {
    this.sender = sender;
    this.receiver = receiver;
    this.message = message;
}

public Chat(){

}

public String getSender() {
    return sender;
}

public void setSender(String sender) {
    this.sender = sender;
}

public String getReceiver() {
    return receiver;
}

public void setReceiver(String receiver) {
    this.receiver = receiver;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}
}

【问题讨论】:

  • 当您执行 setAdapter 时,您正在 for 循环中创建多个适配器,看看那一行,您应该只使用数据创建一个适配器实例
  • @GastónSaillén 试图将适配器和 setAdapter 移出 for 循环。没有改变应用程序仍然因相同的错误而崩溃。但是谢谢你的注意。

标签: java android firebase firebase-realtime-database


【解决方案1】:

现在尝试:

  1. 更改onDataChange()回调,分配适配器和 构建完整数据后的 recyclerView(在 for 循环之外)
  2. 在继续之前检查dataSnapshot.exits() 是否为真

    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    
        if (!dataSnapshot.exits())
            return;
    
        mChat.clear();
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Chat chat = snapshot.getValue(Chat.class);
    
            assert chat != null;
            if ( chat.getSender().equals(myID) &&  chat.getReceiver().equals(userID) ||
                 chat.getSender().equals(userID) &&  chat.getReceiver().equals(myID)) {
                mChat.add(chat) ;
            }
    
        }
    
        messageAdapter = new MessageAdapter(MessageActivity.this, mChat, imageURL);
        recyclerView.setAdapter(messageAdapter);
    }
    

【讨论】:

  • 赞恩。问题不是适配器。他的数据库值不会映射到他的 POJO 类
  • 条件为假,表示dataSnapshot确实存在。并导致 for 循环工作和应用程序崩溃。
【解决方案2】:

看看你的数据库是这样的:

Chats 
  Hhokjvvvcccxddtyiii
          sender=someone
          receiver = some1
          message = hello

你错过了每个孩子都有一个Id,所以你不能这样做:

 Chat chat = snapshot.getValue(Chat.class);

值将为空,这就是为什么;

 String sender = snapshot.child("sender").getValue()).toString();
 String receiver = snapshot.child("receiver").getValue()).toString();
 String message = snapshot.child("message").getValue()).toString();

为你工作。

编辑 做:

 DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Chats");
   Query query = ref.orderByKey();

   query.addValueEventListener(new ValueEventListener() 
       {

    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        mChat.clear();
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Chat chat = snapshot.getValue(Chat.class);

            assert chat != null;
            if ( chat.getSender().equals(myID) &&  chat.getReceiver().equals(userID) ||
                 chat.getSender().equals(userID) &&  chat.getReceiver().equals(myID)) {
                mChat.add(chat) ;
            }


        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError 
    databaseError) {
    }

});

【讨论】:

  • 我编辑问题以包含数据库的图像。我认为这很好。如果没有,请纠正我。此外,您在回答中提到的方法(我在问题中使用的代码)对我不起作用:(
  • 感谢您的宝贵时间,但仍然无法正常工作(同样的错误)。快照变量包含所有数据,但聊天变量为空。现在心情不好。
  • 我可以看看你的聊天课吗??
  • 刚刚编辑了问题并包含了聊天类
  • 并尝试在 if 语句中添加新条件,并且应用程序不再崩溃我将其添加到 case-4 中(在问题中)。
【解决方案3】:

首先,感谢所有试图提供帮助的人。

经过这么多时间和研究,我找到了解决问题的方法,结果表明 readMessage 方法从一开始就工作得很好:)

错误出现在发送消息方法中(顺便说一句,它工作得很好!)。

原来的代码是这样的:

private void sendMessage(String sender, String receiver, String message) {

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();

    HashMap<String, Object> hashMap = new HashMap<>();
    hashMap.put("sender: ", sender);
    hashMap.put("receiver: ", receiver);
    hashMap.put("message: ", message);

    reference.child("Chats").push().setValue(hashMap);
}

正确的代码是:

private void sendMessage(String sender, String receiver, String message) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();

    HashMap<String, Object> hashMap = new HashMap<>();
    hashMap.put("sender", sender);
    hashMap.put("receiver", receiver);
    hashMap.put("message", message);

    reference.child("Chats").push().setValue(hashMap);
}

如果你没有注意到区别,它在 hashMap.put (sender: )、(receiver: ) 和 (message: ) 中。

【讨论】:

    猜你喜欢
    • 2017-06-23
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多