In the below code, I'm doing is what I am checking whether EventsRef dataSnapshot exists or not, if dataSnapshot exists = I am getting some values and storing it in a list and passing that list values to recyclerView method ,in that it displays those values, and my problem is if 2 users in online and both of them getting displayed those details , if user1 removes that reference from firebase database by deleting that event, user2 getting error and getting out of the application . I used child event listener as in the below code but it doesn't works as well . and if i use if else condtions inside the child event listener inside on child Added it also doesn't works , So please help me to solve this both issues .Thanks in advance.
EventsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
if (dataSnapshot.exists())
{
EventsRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s)
{
EventsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
if (dataSnapshot.exists())
{
for (DataSnapshot ds : dataSnapshot.getChildren())
{
String eventId = ds.child("Eid").getValue(String.class);
String gender = ds.child("Gender").getValue(String.class);
String serveCount = ds.child("Serve").getValue(String.class);
list.add(eventId);
list2.add(gender);
list3.add(serveCount);
}
if (list.size() != 0)
{
for (int i = 0; i < list.size(); i++)
{
RecyclerView(list.get(i), list2.get(i), list3.get(i));
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot)
{
Toast.makeText(WorkerMyEventActivity.this, "Event removed", Toast.LENGTH_SHORT).show();
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
else
{
progressDialog.dismiss();
TextView txt = (TextView) findViewById(R.id.txt);
txt.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Related
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) {
}
});
So I want to know if there is a way to query based on inner child without having to know the parent in Firebase Database? Here is the exact situation:
As shown in the image, I want to query the entire data snapshot where title = "bj", since I have pushed them automatically so Im unaware of the Key (or parent in this case). Im curious if Fb Query has anyway to look into the nested childs directly? TIA
private void fetchPinnedLocationsForSearchbar(String key) {
Query query = MyApplication.database.getReference("/pins/").child("title").orderByKey().equalTo(key);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Log.e("-->X-DATA-FROM-QUERY", dataSnapshot.toString());
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
final BusinessModel pinItModel = new BusinessModel();
if (((Boolean) dataSnapshot1.child("ifBusiness").getValue())) {
if
BusinessModel pinItModelTest = dataSnapshot1.getValue(BusinessModel.class);
Log.e("->PicCount", pinItModelTest.getPicCount() + "");
//
_data.add(pinItModelTest);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
So I found the answer from another post on StackOverFlow that suggested the solution should be something like:
FirebaseDatabase.getInstance().getReference("pins").orderByChild("title").equalTo("bj").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.e("-->X--ChildAddedQUERY", dataSnapshot.toString()+"---"+s);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I added data in Firebase Realtime Database and set addChildEventListener using below code.
private DatabaseReference mFirebaseDatabaseRef;
mFirebaseDatabaseRef = FirebaseDatabase.getInstance().getReference("user").child("details");
for (int i = 0; i < result.size(); i++) {
String id = mFirebaseDatabaseRef.push().getKey();
String name = result.get(i).getName();
Details details = new Details();
appDetails.setName(name);
appDetails.setLabel(result.get(i).getLabel());
appDetails.setIconbase64(result.get(i).getIconbase64());
mFirebaseDatabaseRef.child(id).setValue(details );
}
addEventListener();
Add Child event listener method.
private void addEventListener() {
mFirebaseDatabaseRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
Toast.makeText(mContext, "Child Changed", Toast.LENGTH_LONG).show();
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
Log.d("Realtime", "s");
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("Realtime", "s");
}
});
}
Now when I change data in Database, onChildChanged of addChildEventListener is called only for 1st time. but when I again change data in Datbase, no onChildChanged triggered.
I want to trigger onChildChanged every time when I update Data in
Datbase.
you need to call your data in onChildAdded() method instead of onChildChanged() method
private void addEventListener() {
mFirebaseDatabaseRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
Toast.makeText(mContext, "Child Changed", Toast.LENGTH_LONG).show();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
Toast.makeText(mContext, "Child Changed", Toast.LENGTH_LONG).show();
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
Log.d("Realtime", "s");
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Log.d("Realtime", "s");
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("Realtime", "s");
}
});
}
I found the Solution,
I restart my app for some reason that is the main issue.
So I again add addChildEventListener in onCreate method and all the thing is working as expected.
I have Done this:
adapter.getRef(currentPosition).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
adapterKey = dataSnapshot.getChildren().toString();
Log.i("adapterKey",adapterKey);
}
#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) {
}
});
I want to retrieve the Id's generated by firebase in order to access the inner data to EndUsers node. How can I do that?
Try like this
for(DataSnapshot snapshot:dataSnapshot.getChildren()){
//snapshot.getKey()
//snapshot.getValue()
}
DatabaseReference mDatabaseReference; //you must initialize it
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
Log.i(TAG, "the key is : " + child.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The first 2 keys dont have child but others have them. I'm able to display the child elements when there is only one parent and I can display Admin/User details using data object model but how to display parent elements(Bright Kid Test & others) in Listview?
This is an image of Firebase Database:
Code:
listView = (ListView)findViewById(R.id.preschool_list);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,list);
listView.setAdapter(adapter);
databaseReference = FirebaseDatabase.getInstance().getReference("Preschools");
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String value = dataSnapshot.getValue(String.class);
list.add(value);
adapter.notifyDataSetChanged();
}
#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) {
}
});
If there is only one child of preschools then it is displayed else no value is shown.
I've got the answer with datasnapshot.getChildren().
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dsp : dataSnapshot.getChildren())
{
list.add(String.valueOf(dsp.getKey()));
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You want to display text Bright Kid LL, Bright Kid Mont, Bright Kid Test in list view, don't you? You can get them by getKey()
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot recipeSnapshot : dataSnapshot.getChildren()) {
String key = recipeSnapshot.getKey();
list.add(key);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});