The Employee 123
The Employee 123

Reputation: 504

Android - Firebase - Failed to convert value of type java.util.HashMap to String

Aim

Save data within the Group Chat node

Current Database Tree

enter image description here

Within the Group Chats node, the user's messages will be sent and stored within the user's selected group chat.

As shown in the database tree, the user has sent a message saying "Hello" and his name is retrieved from the Users node

Desired Database Tree

enter image description here

The ---Msg ID--- is automatically generated

The ---User ID--- is retreived from the Users node

Problem

The function to allow the user to send message Only Worked Once which was the FIRST time. The following times that the app was deployed, it crashed when the user logged in.

Error - Logcat

com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String

ChatActivity Class - Send Chat Message function

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        jGroupChatName = getIntent().getExtras().get("groupChatName").toString();
        jUserName = getIntent().getExtras().get("groupUserName").toString();
        jUserNeighbourhood = getIntent().getExtras().get("groupUserHome").toString();

        jChatToolbar = (Toolbar) findViewById(R.id.allUSersToolBar);

        jFirebaseCurrentUser = FirebaseAuth.getInstance().getCurrentUser();

        /*UserID Start - I was trying to retrieve the current user ID and add it to the Group Chat node, 
          under the selected Group Chat */
        assert jFirebaseCurrentUser != null;
        final String currentUserID = jFirebaseCurrentUser.getUid();
        jChatRoot = FirebaseDatabase.getInstance().getReference().child("Group Chats").child(jGroupChatName).child(currentUserID);
        /*UserID End*/

        jChatMessageText = (EditText) findViewById(R.id.chatMessageText);
        jChatSendTextBtn = (ImageButton) findViewById(R.id.chatSendTextBtn);

        jChatSendTextBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Map<String, Object> groupMap = new HashMap<String, Object>();
                jGroupKey = jChatRoot.push().getKey();
                jChatRoot.updateChildren(groupMap);

                // Based on the UserID code at the top, the "currentUserID" is added as shown below
                // My intentions are to have the UserID saved under the name of the Group Chat
                // jGroupKey = (Name of selected Group Chat)

                DatabaseReference groupMessageRoot = jChatRoot.child(jGroupKey).child(currentUserID);
                Map<String, Object> groupMap2 = new HashMap<String, Object>();
                groupMap2.put("name", jUserName);
                groupMap2.put("msg", jChatMessageText.getText().toString());

                groupMessageRoot.updateChildren(groupMap2);
            }
        });
    }

Linked Question

Android - Firebase - Send Users to Chat Room

Future Implementations

In the future, I intend to allow the user to send pictures and video recordings by writing a code to allow the user to access their phone camera or gallery and send the pics and vids data into the Group Chats node, under the selected Group name. I would also like to retrieve data after sending, but of course, I will leave those in future questions if I am unable to solve them.

Upvotes: 2

Views: 2043

Answers (1)

Mehmed
Mehmed

Reputation: 3040

Branching of your desired database is unnecessary. You are creating an unnecessary level using UID of users. Instead, merge this layer down, i.e. combine uid, message and name. You can then use someRef.orderByKey("uid").equalTo("<user_uid>") in case you need specific user's records within that path, for example chat messages.

So, create a class called ChatMessage:

public class ChatMessage {

    private String uid;
    private String name;
    private String message;
    private Long creationTime;

    public ChatMessage() {
        // Default constructor required for calls to DataSnapshot.getValue(ChatMessage.class)
    }

    public ChatMessage(String uid, String name, String message) {
        this.uid = uid;
        this.name = name;
        this.message = message;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMessage() {
        return message;
    }

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

    public java.util.Map<String, String> getCreationTime() {
        return ServerValue.TIMESTAMP;
    }

    @Exclude
    public Long getCreationTimeLong() {
        return creationTime;
    }

    public void setCreationTime(Long creationTime) {
        this.creationTime = creationTime;
    }
}

Then update your code as follows:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    chatGroupName = getIntent().getStringExtra(CHAT_GROUP_NAME);
    userKey = getIntent().getStringExtra(USER_KEY);
    user = getIntent().getParcelableExtra(USER);

    jChatToolbar = (Toolbar) findViewById(R.id.allUSersToolBar);
    jChatMessageText = (EditText) findViewById(R.id.chatMessageText);
    jChatSendTextBtn = (ImageButton) findViewById(R.id.chatSendTextBtn);

    jChatSendTextBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            sendMessage();
        }
    });
}

private void sendMessage() {
    String userMessage = jChatMessageText.getText().toString();
    chatGroupRef = FirebaseDatabase.getInstance().getReference().child("Group Chats").child(chatGroupName);

    if (!TextUtils.isEmpty(userMessage)) {
        String newChatMessageKey = chatGroupRef.push().getKey();
        ChatMessage newChatMessage = new ChatMessage(userKey, user.getName(), userMessage);
        chatGroupRef.child(newChatMessageKey).setValue(newChatMessage);
    }
}

Upvotes: 1

Related Questions