Namenots
Namenots

Reputation: 25

Accessing a child within a child firebase

This is not a duplicate. I am trying to access a child within a child in firebase and then putting that child into a recycler adapter. It won't show in the recycler adapter. There is a similar question on here to this but when implementing it, it still doesn't work.

Currently using an adapter, a messages object and a fragment.

Fragment Activity

    private ArrayList<Messages> results = new ArrayList<>();
    private void listenForChat() {
        final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
                .child("receivedMessages");
        messageUrlDb = userDb.child("messageUrl");

        messageUrlDb.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String message = "";
                if (dataSnapshot.child("messageUrl").getValue() != null)
                    message = dataSnapshot.child("messageUrl").getValue().toString();
                Messages obj = new Messages(message, name, image);
                if (!results.contains(obj)) {
                    results.add(obj);
                    messagesList.setAdapter(mAdapter);
                    mAdapter.notifyDataSetChanged();
                    initializeDisplay();
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) { }
        });
    }

public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolders> {


    private List<Messages> mMessageList;
    private List<UserObject> usersList;
    private Context context;
    private DisplayTextFragment displayTextFragment;
    private String message;



    public ChatAdapter(List<Messages> mMessageList, Context context) {

        this.mMessageList = mMessageList;
        this.context = context;

    }

    @Override
    public ChatViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_layout, null);
        ChatViewHolders rcv = new ChatViewHolders(v);
        return rcv;

    }

    @Override
    public void onBindViewHolder(final ChatViewHolders holder, int position) {

        holder.messageText.setText(mMessageList.get(position).getMessage());

    }

    @Override
    public int getItemCount() {
        return mMessageList.size();
    }


    public class ChatViewHolders extends RecyclerView.ViewHolder {

        public TextView messageText, timeSent, mName;
        ImageView mProfile;
        LinearLayout mLayout;

        public ChatViewHolders(View view) {
            super(view);
            messageText = (TextView) view.findViewById(R.id.message_text);
            mLayout = itemView.findViewById(R.id.layout);
        }
    }
}

Firebase database

I am trying access (messageUrl) users -> receivedMessages -> messageUrl. However as there is a key they I assume it doesn't as far as messagesUrl. For the recycler adapter it needs take in messagesUrl as a string and update accordingly but I just can't do it.

If any more code is needed I can post. Thank you.

Upvotes: 0

Views: 52

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598847

This is how you're attaching your ValueEventListener:

final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
        .child("receivedMessages");
messageUrlDb = userDb.child("messageUrl");

messageUrlDb.addValueEventListener(new ValueEventListener() {

If we take the path from this code, you're attaching the listener to /users/$uid/receivedMessages/messageUrl. This path doesn't exist in the data you showed, so your onDataChanged will get called with an empty snapshot.

If you want to read all messages for the user, you should attach your listener to /users/$uid/receivedMessages and parse the snapshot inside onDataChanged:

final DatabaseReference userDb = FirebaseDatabase.getInstance().getReference().child("users").child(currentUid)
        .child("receivedMessages");
userDb.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot userMessages: dataSnapshot.getChildren()) {
            for (DataSnapshot messageSnapshot: userMessages.getChildren()) {
                System.out.println(messageSnapshot.getKey()+": "+messageSnapshot.getChild("messageUrl").getValue(String.class));
            }
        }
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) { 
        throw databaseError.toException(); // don't ignore errors
    }
});

This loops over the two level of child nodes you have under the user's receivedMessages node.

Upvotes: 2

Related Questions