I have this database
I read key "20160877" to update type this is easy because there is one key.
by this way ==>
table_user.child("20160877").child("type").setValue("2");
If I put many keys like "20160877" and have value inside it and want to update type in all type in all keys how can I did this?
I tried this way but it create new key then update type in it, I want to update the existing data and not create new data
DatabaseReference table_user;
FirebaseDatabase database;
String id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_main);
database = FirebaseDatabase.getInstance();
table_user = database.getReference("Users");
}
public void current_member(View view) {
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
id =snapshot.getKey();
table_user.child(id).child("type").setValue("1");
Toast.makeText(AdminMainActivity.this, "تم تفعيل صفحة الاعضاء الحاليون", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
public void active_C_page(View view) {
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
id =snapshot.getKey();
table_user.child(id).child("type").setValue("2");
Toast.makeText(AdminMainActivity.this, "تم تفعيل صفحة الترشح", Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
If you want to update the status of all users, you'll need to loop over the user nodes in the snapshot in your onDataChange.
So something like:
table_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot userSnapshot: snapshot.getChildren()) {
id = userSnapshot.getKey();
table_user.child(id).child("type").setValue("1");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
Or you can directly get the reference from the userSnapshot
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot userSnapshot: snapshot.getChildren()) {
userSnapshot.getReference().child("type").setValue("1");
}
}
Related
referenc2= FirebaseDatabase.getInstance().getReference("messageCounter").child("node");
referenc2.addValueEventListener(new ValueEventListener() {
public void onDataChange(#NonNull DataSnapshot snapshot) {
String count= Integer.parseInt(snapshot.child("cnt").getValue(String.class));
}
#Override public void onCancelled(#NonNull DatabaseError error) {
}
});
I need to retrieve the value stored inside the cnt node into a variable in android studio. can anyone help?
if you want to get value of specific node or child node like this
Here if you want to get child node(address) value. You can get it in this way
DatabaseReference db= FirebaseDatabase.getInstance().getReference().child("RouteCounter").child("node");
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
String email = userSnapshot.child("cnt").getValue(String.class);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
In the Firebase, I have a “usuario” node with the data for each registered user. I want to retrieve the Ids of a user's friends and through these ID's show in RecyclerView the data of each friend (identifier, name and photo address).
My structure in Firebase:
I tried this code, but it doesn't work. the list is empty:
ref = ConfigFirebase.getFirebaseDatabase().child("usuarios"); //code in OnCreate
//My method
ref = ref.child(idUserLog).child("friends");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot idFriends: dataSnapshot.getChildren()){
DataUserFriend dataUserFriend = idFriends.getValue(DataUserFriend.class);
String id = dataUserFriend.getIdUser();
ref.child(id).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataUser dataUser = dataSnapshot.getValue(DataUser.class);
listFriends.add(dataUser);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
listFriendsAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
What is wrong? or should i try another way?
Solution:
ref = ConfigFirebase.getFirebaseDatabase().child("usuarios"); //code in OnCreate
//My method
ref = ref.child(idUserLog).child("friends");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final int numFriends = (int) dataSnapshot.getChildrenCount();
if(numFriends != 0){
for (DataSnapshot idFriends: dataSnapshot.getChildren()){
DataUserFriend dataUserFriend = idFriends.getValue(DataUserFriend.class);
String id = dataUserFriend.getIdUser();
ref = ConfigFirebase.getFirebaseDatabase().child("usuarios").child(id);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataUser dataUser = dataSnapshot.getValue(DataUser.class);
listFriends.add(dataUser);
if(listFriends.size() == numFriends){
listFriendsAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The call to listFriendsAdapter.notifyDataSetChanged() should happen in the same method that updates listFriends.
So:
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot idFriends: dataSnapshot.getChildren()){
DataUserFriend dataUserFriend = idFriends.getValue(DataUserFriend.class);
String id = dataUserFriend.getIdUser();
ref.child(id).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
DataUser dataUser = dataSnapshot.getValue(DataUser.class);
listFriends.add(dataUser);
listFriendsAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
If you want to call listFriendsAdapter.notifyDataSetChanged() only when all friends have been added to listFriends, you can keep a count of how often the inner onDataChange has been called and compare that to the number of friend IDs.
You have added SingleValueEvent listener on database reference object due to which the callback isn't getting fired immediately. You should create a Query and add the SingleValueEvent listener for it. For example:
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference("usuarios");
Query query = mDatabase.child(idUserLog).child("friends");
query .addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// Code to parse and display data
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I am trying to retrieve data from multiple nodes and store them in a Single List. I am able to do that but the problem is data is getting duplicated if I remove list.clear(); in function getTeam2().
Here is the Screenshot of the Database.
Here is The Code
databaseReference = FirebaseDatabase.getInstance().getReference("Teams")
.child(team1).child("Players");
databaseReference.orderByChild("playertype").equalTo("Wk")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
mList.clear();
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Player player = dataSnapshot.getValue(Player.class);
mList.add(player);
getTeam2(mList);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
return view;
}
private void getTeam2(final List<Player> mList) {
DatabaseReference team = FirebaseDatabase.getInstance().getReference("Teams")
.child(team2).child("Players");
team.orderByChild("playertype").equalTo("Wk")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Player player = dataSnapshot.getValue(Player.class);
mList.add(player);
bar.setVisibility(View.INVISIBLE);
}
adapter = new PlayerAdapter(getContext(), WKFragement.this.mList);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
If I use list.clear(); in team2 function then it only displays the members of team2.
What changes should I make?
I have the following code that is supposed to read data from Firebase and add it to array lists namesList and addressList. I logged the values on onDataChange events. The logcat shows that data is infact read but when I iterate the list, it is of size zero. Can anyone please help me regarding this:
#Override
public void onStart() {
super.onStart();
activeOrders = FirebaseDatabase.getInstance().getReference().child("Ordered Items");
activeOrders.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot child: snapshot.getChildren())
{
key = child.getKey().toString();
name = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("name");
address = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("shippingAddr");
name.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.i("Username", snapshot.getValue().toString());
namesList.add(snapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
address.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.i("Address", snapshot.getValue().toString());
addressList.add(snapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Toast.makeText(this, "Size:" + namesList.size(), Toast.LENGTH_SHORT).show();
for(int i=0; i<namesList.size(); i++){
Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
}
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signOutUser();
}
});
You are iterating the list in the main thread, while the actual list takes some time to come back from firebase, that is because all firebase callbacks runs in background thread inclusively
So, the below code runs in main thread before the actual data comes in
for(int i=0; i<namesList.size(); i++){
Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
}
And the below code runs in firebase background thread
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.i("Username", snapshot.getValue().toString());
namesList.add(snapshot.getValue().toString());
}
To solve this you can transfer the iteration as below
activeOrders.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot child: snapshot.getChildren())
{
key = child.getKey().toString();
name = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("name");
address = FirebaseDatabase.getInstance().getReference().child("Users").child(key).child("shippingAddr");
name.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.i("Username", snapshot.getValue().toString());
namesList.add(snapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
address.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.i("Address", snapshot.getValue().toString());
addressList.add(snapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
for(int i=0; i<namesList.size(); i++){
Toast.makeText(this, namesList.get(i).toString(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
This is my Database in Firebase
I want to get the values of Students under Courses
and then I want to delete the course name under courses in users(that username match the values I got from Courses/Students )
after clicking on a button
This is my code
DatabaseReference mCourseDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Courses").child(courseModel.getCourseName());
final DatabaseReference mStudentDB = FirebaseDatabase.getInstance().getReference().child("Users");
mCourseDatabaseReference.child("Students").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(final DataSnapshot snapshot1 : dataSnapshot.getChildren()){
final User student = snapshot1.getValue(User.class);
mStudentDB.orderByChild("userName").equalTo(student.getUserName()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data: dataSnapshot.getChildren())
{
String stuserkey = data.getKey();
mStudentDB.child(stuserkey).child("Courses").child(courseModel.getCourseName()).removeValue();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }});
but it doesn't work.
can you help me, please?
thanks.