-1

I have a very serious problem. I am using a RecyclerView to populate data(a list of users) from Firebase into my application. Now the problem is that how to reference their respective userIds when a user clicks any of them so it can be used to set the title of the activity's action bar that will be opened. I tried using the getRef() method but it could not be resolved. Below is my code.

My StudentsList

package com.dreamlazerstudios.gtuconline;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

import de.hdodenhof.circleimageview.CircleImageView;

import static android.content.ContentValues.TAG;

public class StudentsList extends AppCompatActivity {

DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<Students> listData;
RecyclerView recyclerView;
StudentsList.MyAdapter adapter;

private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private FirebaseDatabase mFirebaseDatabase;
private String userID;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_students_list);
    setTitle("List of Students");
    recyclerView = findViewById(R.id.students_list);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    listData = new ArrayList<>();
    adapter = new StudentsList.MyAdapter(listData);
    adapter.setHasStableIds(true);

    GetDataFirebase();

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading Data...");
    progressDialog.show();

    mAuth = FirebaseAuth.getInstance();
    mFirebaseDatabase = FirebaseDatabase.getInstance();
    myRef = mFirebaseDatabase.getReference();
    final FirebaseUser user = mAuth.getCurrentUser();
    userID = user.getUid();

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                // User is signed in

                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
            } else {
                // User is signed out
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
            // ...
        }
    };

}

void GetDataFirebase() {

    databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child("Students");

    databaseReference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            Students students = dataSnapshot.getValue(Students.class);

            listData.add(students);

            recyclerView.setAdapter(adapter);

            progressDialog.dismiss();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


}

@Override
public void onStart() {
    super.onStart();

    mAuth.addAuthStateListener(mAuthListener);

}

public class MyAdapter extends RecyclerView.Adapter<StudentsList.MyAdapter.ViewHolder> {

    List<Students> list;

    public MyAdapter(List<Students> List) {
        this.list = List;
    }

    @Override
    public void onBindViewHolder(final StudentsList.MyAdapter.ViewHolder holder, final int position) {

        Students students = list.get(position);

        String list_user_id = getRef(position).getKey();

        holder.news_topic.setText(students.getName());
        holder.news_body.setText(students.getProgramme());

        if (students.getOnline() == true) {
            holder.online.setVisibility(View.VISIBLE);
        } else {
            holder.online.setVisibility(View.INVISIBLE);
        }

        Picasso.with(holder.news_image.getContext()).load(students.getThumb_image()).placeholder(R.drawable.student_icon_17870).into(holder.news_image);

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

                Intent chat_intent = new Intent(StudentsList.this, ChatActivity.class);
                chat_intent.putExtra("user_id", list_user_id );
                startActivity(chat_intent);
            }
        });

    }

    @NonNull
    @Override
    public StudentsList.MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.users_list_layout, parent, false);

        return new StudentsList.MyAdapter.ViewHolder(view);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView news_topic, news_body;
        CircleImageView news_image;
        ImageView online;

        public ViewHolder(View itemView) {
            super(itemView);

            news_topic = itemView.findViewById(R.id.user_single_name);
            news_body = itemView.findViewById(R.id.user_single_status);
            news_image = itemView.findViewById(R.id.user_single_image);
            online = itemView.findViewById(R.id.online_status_icon);
        }

    }

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

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

}

My model class

package com.dreamlazerstudios.gtuconline;

/**
 * Created by Gabriel Hagan on 16/05/2018 at 23:10.
*/
public class Students {

String name;
String programme;
String thumb_image;
Boolean online;

public Boolean getOnline() {
    return online;
}

public void setOnline(Boolean online) {
    this.online = online;
}

public Students() {
}

public Students(String name, String programme, String thumb_image, Boolean online) {
    this.name = name;
    this.programme = programme;
    this.thumb_image = thumb_image;
    this.online = online;
}

public String getName() {
    return name;
}

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

public String getProgramme() {
    return programme;
}

public void setProgramme(String programme) {
    this.programme = programme;
}

public String getThumb_image() {
    return thumb_image;
}

public void setThumb_image(String thumb_image) {
    this.thumb_image = thumb_image;
}

}

My ChatActivity

package com.dreamlazerstudios.gtuconline;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class ChatActivity extends AppCompatActivity {

private DatabaseReference rootRef;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private String userID;
private String mChatUser;

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

    rootRef = FirebaseDatabase.getInstance().getReference();
    mAuth = FirebaseAuth.getInstance();
    final FirebaseUser user = mAuth.getCurrentUser();
    userID = user.getUid();

    mChatUser = getIntent().getStringExtra("user_id");

    rootRef.child("Users").child("Students").child(mChatUser).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            String chat_user_name = dataSnapshot.child("name").getValue().toString();
            setTitle(chat_user_name);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

    rootRef.child("Chat").child(userID).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}
}

My database snapshot

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193

2 Answers2

1

You can get the key from the DataSnapshot you are getting in onChildAdded. Instead of having a list of students in your adapter, you could keep the list of DataSnapshots. Then you could do something like this:

In StudentsList, change:

List<Students> listData;

To:

List<DataSnapshot> listData;

Also, change onChildAdded:

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {

        listData.add(dataSnapshot);
        //Should probably move these since they don't need to get called for every item.
        recyclerView.setAdapter(adapter);  
        progressDialog.dismiss();
    }

Then in your adapter:

public class MyAdapter extends RecyclerView.Adapter<StudentsList.MyAdapter.ViewHolder> {

    List<DataSnapshot> list;

    public MyAdapter(List<DataSnapshot> List) {
        this.list = List;
    }
    @Override
    public void onBindViewHolder(final StudentsList.MyAdapter.ViewHolder holder, final int position) {

        DataSnapshot studentSnapshot = list.get(position);

        String list_user_id = studentSnapshot.getKey();

        Students students = studentSnapshot.getValue(Students.class)

        //The rest unchanged
Cody W.
  • 376
  • 2
  • 6
  • What error did you get? Did you change `listData` type to DataSnapshot and add the snapshots instead of students in onChildAdded? – Cody W. May 23 '18 at 14:07
  • How do I do that? I am a beginner so please help –  May 23 '18 at 14:14
  • Thanks Cody. So now how do I get the data for the name, programme and online nodes as well. What you're imposing gives me more errors. –  May 23 '18 at 14:41
  • Did you add final line I put in onBindViewHolder? `Students students = studentSnapshot.getValue(Students.class)` – Cody W. May 23 '18 at 14:45
  • now the listdata variable returns an error. adapter = new StudentsList.MyAdapter(listData); –  May 23 '18 at 14:54
  • error: incompatible types: List cannot be converted to List –  May 23 '18 at 15:02
  • Please check that you made all of the changes I suggested in my edit. listData would be defined as `List listData` – Cody W. May 23 '18 at 15:10
0

Inside onBindViewHolder method you can get the key of the user that you are looking for using the following line of code:

String list_user_id = getItem(position);

getRef() is used to obtain a reference to the source location for the snapshot. So you can only use this method on a snapshot object. It returns a DatabaseReference and takes no argument. Below an example:

DatabaseReference ref = dataSnapshot.child("users").getRef();
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • There is no method like "getItem" in onBindViewHolder. It returned an error. –  May 23 '18 at 13:56
  • I rather did this. chat_intent.putExtra("user_name", students.getName()); And I was able to get the name of that respective user that was clicked. But I need to get the userID of that user that was clicked and store it in the database. How do I do that? –  May 23 '18 at 13:57
  • Yes it is a method like "getItem" in onBindViewHolder. What is the error? – Alex Mamo May 23 '18 at 14:07
  • Are you using the last version of the Firebase-UI library? – Alex Mamo May 23 '18 at 14:17
  • I am not using the firebase ui library. When I try to use it, I get some sort of error. So I can't use it –  May 23 '18 at 14:20
  • That would mean I would have to migrate to the firestore database? –  May 23 '18 at 14:26
  • Is there no way I would just use the realtime database to solve this error? –  May 23 '18 at 14:27
  • I'm sorry. Ignore that comment. **[This](https://stackoverflow.com/questions/49383687/how-can-i-retrieve-data-from-firebase-to-my-adapter/49384849)** is how you can retrieve data from a Firebase Realtime database and display it in a `RecyclerView` using `FirebaseRecyclerAdapter`. – Alex Mamo May 23 '18 at 14:28
  • What? I'm already displaying data in my recyclerview. I just need to get the userid of that data(the user data) that has been populated into the recyclerview. That is why I tried the "String list_user_id = getRef(position).getKey;" But it didn't work out. –  May 23 '18 at 14:34
  • Add the user id as a property in your object model and get using this: `dataSnapshot.child("userId").getValue().toString()`. Can you do that? – Alex Mamo May 23 '18 at 14:37
  • Yes I can. So means there's no other way apart from this? –  May 23 '18 at 14:42
  • There is, the way I have exaplined in my answer but I cannot see the reason why `getItem(position)` does not work. So this is an alternative. Try it and keep me posted. – Alex Mamo May 23 '18 at 14:50
  • 1
    I definitely will –  May 23 '18 at 14:58
  • Thanks for your help Alex. But Cody's answer helped me. –  May 23 '18 at 15:59