Ok so I have made a CardView hold one database item(in this case a football player) and adapted it in a RecyclerView.
My Firebase Database looks like this:
Players:
|---Goalkeepers:
|--GoalkeeperName
|--(And some other data fields)
|---Defenders:
|---Midfielders:
|---Attackers
My database reference looks like this:
playersDatabase = FirebaseDatabase.getInstance().getReference("Players").child("Goalkeepers");
If I leave the reference as ("Players"), it will give me 4 empty fields representing the Goalkeeper, Defenders, Midfielders and Attackers branch.
How do I display all data from all Position branches such as Goalkeeper, Defenders, Midfielders and Attackers?
Also is there any way of displaying all the players in an organised way with headings in my layout so it looks like this?
Goalkeepers(heading)
Goalkeeper1
Goalkeeper2
Defenders (heading)
Defender1
Defender2
This is the code from the actual app:
public class PlayerList extends AppCompatActivity {
private RecyclerView mPlayerList;
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playersRef = rootRef.child("Players");
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_squad_list);
//playersDatabase = FirebaseDatabase.getInstance().getReference("Players").child("Goalkeepers");
playersRef.keepSynced(true);
//new code
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String typeOfPlayer = ds.getKey();
Log.d("TAG", typeOfPlayer);
for(DataSnapshot dSnapshot : dataSnapshot.child(typeOfPlayer).getChildren()) {
String player = dSnapshot.getKey();
Log.d("TAG", " " + player);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
playersRef.addListenerForSingleValueEvent(valueEventListener);
mPlayerList = (RecyclerView) findViewById(R.id.my_recycle_view);
mPlayerList.setHasFixedSize(true);
mPlayerList.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Player, PlayerViewHolder>firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Player, PlayerViewHolder>(Player.class, R.layout.player_row, PlayerViewHolder.class, playersRef) {
#Override
protected void populateViewHolder(PlayerViewHolder viewHolder, Player model, int position) {
viewHolder.setPlayerName(model.getPlayerName());
viewHolder.setPlayerSurname(model.getPlayerSurname());
viewHolder.setPlayerPosition(model.getPlayerPosition());
}
};
mPlayerList.setAdapter(firebaseRecyclerAdapter);
}
public static class PlayerViewHolder extends RecyclerView.ViewHolder{
View mView;
public PlayerViewHolder(View itemView){
super(itemView);
mView = itemView;
}
public void setPlayerName (String playerName){
TextView textViewName = (TextView) mView.findViewById(R.id.textViewName);
textViewName.setText(playerName);
}
public void setPlayerSurname (String playerSurname){
TextView textViewName = (TextView) mView.findViewById(R.id.textViewSurname);
textViewName.setText(playerSurname);
}
public void setPlayerPosition (String playerPosition){
TextView textViewName = (TextView) mView.findViewById(R.id.textViewPosition);
textViewName.setText(playerPosition);
}
}
}
Any help is appreciated. Thanks
To display those players accordingly to the following database structure:
Goalkeepers
Goalkeeper1
Goalkeeper2
Defenders
Defender1
Defender2
Please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playersRef = rootRef.child("Players");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String typeOfPlayer = ds.getKey();
Log.d("TAG", typeOfPlayer);
DatabaseReference playerRef = playersRef.child(typeOfPlayer);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
String player = dSnapshot.getKey();
Log.d("TAG", " " + player);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
playerRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
playersRef.addListenerForSingleValueEvent(valueEventListener);
Edit:
According to your edited post, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference playersRef = rootRef.child("Players");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String typeOfPlayer = ds.getKey();
Log.d("TAG", typeOfPlayer);
for(DataSnapshot dSnapshot : dataSnapshot.child(typeOfPlayer).getChildren()) {
String player = dSnapshot.getKey();
Log.d("TAG", " " + player);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
playersRef.addListenerForSingleValueEvent(valueEventListener);
Your result must be:
Attackers
Defenders
Goalkeepers
Goalkeeper1
Midfielders
Try this code ..
private void readData(){
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Players").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String typeOfPlayer = ds.getKey();
Log.d("TAG", typeOfPlayer);
for(DataSnapshot dSnapshot : dataSnapshot.child(typeOfPlayer).getChildren()) {
String player = dSnapshot.getKey();
Log.d("TAG", " " + player);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
and i hope add internet permission into manifest file..
more information refer this link
https://www.simplifiedcoding.net/firebase-realtime-database-crud/
Related
i'm a beginner in android application, could anyone help me and show me how could i retrieve the generated id value node of the current user Id ? please find below my code. Thanks
FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDb = mDatabase.getReference();
FirebaseUser user = firebaseAuth.getCurrentUser();
final String userKey = user.getUid();
mDb.child("students").child(currentuser).getRef().addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String reference = dataSnapshot.getRef().toString();
String userID = dataSnapshot.child("level").getValue(String.class);
textViewStudentName.setText(reference);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Try below to get level:
DatabaseReference fireReference = FirebaseDatabase.getInstance().getReference("students");
fireReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
if(childSnapshot.hasChild(userKey)) {
String userID = childSnapshot.child(userKey).child("level").getValue(String.class);
break;
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I'm trying to return the key and value from my Firebase Database and insert it into a RecycleView adapter but the values won't show up in the app.
I can't wrap my head around this whatsoever.
I tried to show the values in a Toast and it worked but why won't the values be inserted into the RecycleView adapter?
This is the code.
public class test extends AppCompatActivity {
TextView textView;
Button button;
String phone;
String n;
String a;
FirebaseAuth mAuth;
MyRecyclerViewAdapter adapter;
ArrayList<String> info;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Bundle b = new Bundle();
b = getIntent().getExtras();
phone = b.getString("number");
textView = findViewById(R.id.textV);
button = findViewById(R.id.signoutButton);
mAuth = FirebaseAuth.getInstance();
textView.setText(textView.getText().toString() + " as " + phone);
info = new ArrayList<>();
FirebaseDatabase myRef = FirebaseDatabase.getInstance();
DatabaseReference sRef = myRef.getReference("users");
sRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnap : dataSnapshot.getChildren()) {
if (childSnap.getKey().equals(phone)) {
for (DataSnapshot c : childSnap.getChildren()) {
n = c.getKey();
a = c.getValue().toString();
info.add(n);
info.add(a);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
RecyclerView recyclerView = findViewById(R.id.rvInfo);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this, info);
adapter.setClickListener(new MyRecyclerViewAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Toast.makeText(test.this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
}
You can get this using following code
sRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnap : dataSnapshot.getChildren()) {
if (childSnap.getKey().equals(phone)) {
for (DataSnapshot c : childSnap.getChildren()) {
n = c.getKey();
a = c.getValue().toString();
info.add(n);
info.add(a);
}
}
}
notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
You have to add notifyDataSetChanged(); after you fill ArrayList from firebase. Because it's take time to load data from firebase. And your adapter initialised before fill ArrayList from firebase.
Now im trying to create my first Android app.
I'm currently working on a view name Bands which is supposed to create a list (imported from Firebase Database) and link it to a ListView.
As you can see, i have a link to print out the whole bandsList, that way i know the list imported well, and it is...but the ListView is not updated according to the bandsList, so im guessing the problem is in the adapter.
public class Bands extends AppCompatActivity {
ListView listView;
ArrayList<String> bandsList = new ArrayList<>();
ArrayAdapter<String> bandsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bands);
listView = findViewById(R.id.bandsListView);
bandsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, bandsList);
listView.setAdapter(bandsAdapter);
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Bands");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot band : dataSnapshot.getChildren()) {
String bandName = band.child("Name").getValue(String.class);
bandsList.add(bandName);
System.out.println("bandsList :" + bandsList);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//String BandName =dataSnapshot.getValue(String.class);
for (DataSnapshot band : dataSnapshot.getChildren()) {
String bandName = band.child("Name").getValue(String.class);
System.out.println(bandName);
bandsList.add(bandName);
System.out.println(bandsList);}
}
#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) {
}
});
}
}
Just add bandsAdapter.notifyDataSetChanged() after the Firebase-Callback:
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot band : dataSnapshot.getChildren()) {
String bandName = band.child("Name").getValue(String.class);
bandsList.add(bandName);
System.out.println("bandsList :" + bandsList);
}
bandsAdapter.notifyDataSetChanged();
}
You need to tell the adapter to update the list in both
onDataChange() and onChildAdded() using bandsAdapter.notifyDataSetChanged();
I have the following database and need some help retrieving the name and address from the user which is logged in currently.
I wrote the following code but the information is not showing in the textview
public class UserProfileActivity extends AppCompatActivity {
DatabaseReference userReference = FirebaseDatabase.getInstance().getReference();
TextView userName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_profile);
userName = (TextView) findViewById(R.id.userName);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
userName.setText(name);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
};
}
}
This is what is currently happening when implementing the ValueEventListener
try this:
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userid=user.getUid();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child(userid);
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String address=dataSnapshot.child("address").getValue().toString();
String name=dataSnapshot.child("name").getValue().toString();
userName.setText(name);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Since your datasnapshot is on the child(userid) which is direct child under root node then you don't need to iterate to be able to get the values of the current user.
I have this database:
In Activity A, I click on a class(listitem) and then pass the id of that class to this activity like this:-
so = getIntent().getStringExtra("send_id");
So right now I have the ClassId in this activity inside so. Then I run this query:
myref= FirebaseDatabase.getInstance().getReference().child("ClassStudent");
Query fk=myref.orderByChild("ClassId").equalTo(so);
fk.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
student=dataSnapshot.child("Studentid").getValue().toString();
//a breakpoint here gives student=oyvEbB0128Y90ADzXnL0UwCUy0Z2
}
#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) {
}
}
So in the query I want all the students id that have that classid orderByChild("ClassId").equalTo(so)
Then I create a FirebaseRecycleradapter
FirebaseRecyclerAdapter<Info,ViewHolder> recyclerAdapter=new FirebaseRecyclerAdapter<Info,ViewHolder>(Info.class, R.layout.row, ViewHolder.class, fk) {
#Override
protected void populateViewHolder(final ViewHolder holder, Info model, int position) {
holder.title.setText(student); //a breakpoint here gives student = 7AnhQ7pRwhXDRqytjSUkoJrOB253
}
}
Now the data is appearing(on phone screen) like this:
Result
7AnhQ7pRwhXDRqytjSUkoJrOB253
7AnhQ7pRwhXDRqytjSUkoJrOB253
The above student id is appearing twice, instead it should be:
It should be
7AnhQ7pRwhXDRqytjSUkoJrOB253
oyvEbB0128Y90ADzXnL0UwCUy0Z2
Since both those students are in that class.
I have also overridden, getItemId and getItemViewType
To solve this, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classStudentRef = rootRef.child("ClassStudent");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String Studentid = ds.child("Studentid").getValue(String.class);
Log.d("TAG", Studentid);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
classStudentRef.addListenerForSingleValueEvent(eventListener);
The output will be:
7AnhQ7pRwhXDRqytjSUkoJrOB253
oyvEbB0128Y90ADzXnL0UwCUy0Z2
Edit: To get the name of the student of the coreponding stundet if you need to query your database twice. So, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classStudentRef = rootRef.child("ClassStudent");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String Studentid = ds.child("Studentid").getValue(String.class);
Log.d("TAG", Studentid);
DatabaseReference studentIdRef = rootRef.child("Student").child(Studentid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
studentIdRef.addListenerForSingleValueEvent(valueEventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
classStudentRef.addListenerForSingleValueEvent(eventListener);