Please how do I simply get the child count from a firebase Query. For example Let's say I use a database query with 10 children, how do I get that value because I tried using onChildChanged and getting the value from the snapshot, but it does not work well. This is because at first it will get the number, then it will query again because it has to continuously sync, but because there is not actual child change at the second query it return a value if zero which will replace the original correct value. :/
databaseReference.child("PrinterView").child(uni).child(phone).orderByChild("done").equalTo("No").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Toast.makeText(getActivity(),"Number:"+String.valueOf(dataSnapshot.getChildrenCount()),Toast.LENGTH_LONG).show();
}
#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) {
}
});
Both don't work
databaseReference.child("PrinterView").child(uni).child(phone).orderByChild("done").equalTo("No").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Toast.makeText(getActivity(),"Number:"+String.valueOf(dataSnapshot.getChildrenCount()),Toast.LENGTH_LONG).show();
Vendor_view_Home_fragment.printIndicator.setText(String.valueOf(dataSnapshot.getChildrenCount()));
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Assuming that PrinterView is a direct child of your Firebase root, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("PrinterView").child("Covenant University").child("588");
Query query = yourRef.orderByChild("done").equalTo("No");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long count = dataSnapshot.getChildrenCount();
Log.d("TAG", String.valueOf(count));
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(eventListener);
The problem was this line:
databaseReference.child("PrinterView").child(uni).child(phone).orderByChild("done").equalTo("No").addValueEventListener(new ValueEventListener()
The variable "uni" and "phone" was also provided by a firebase Query E.G It was to get the University and phone number of the current user so I could not just put a static string there.
databaseReference.child("Users").child(mAuth.getCurrentUser().getUid()).child("Phone").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
phone = dataSnapshot.getValue().toString();
// Toast.makeText(getActivity(), phone, Toast.LENGTH_LONG).show();
setPendingList();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
So the issue was that, if the network connection was slow or if the queries were not done yet, those two variables would be empty thereby making the dataSnapshot empty. I will have to sort that out by only allowing that to be queried when the rest are sure to be done. :)
Related
I need to count all the children that are in my Firebase database.
This is the Firebase structure:
Level 1
- CHILD1
- - subchild1
- - subchild2
- CHILD2
- - subchild 1
How can I count the CHILDs from level 1?
(In this example it would need to return 2...)
Query the first level and then in your SnapShot, use : getChildrenCount().
So the query will be something like this:
myRef.child("level1").child("subchild1"). // Your listener after
Check this link.
And here.
Try This
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference ref = db.getReference();
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.e(dataSnapshot.getKey(),dataSnapshot.getChildrenCount() + "");
}
#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) {
}
});
DatabaseReference mDatabaseRef = FirebaseDatabase.getInstance().getReference();
mDatabaseRef.child("level1").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
long count= dataSnapshot.getChildrenCount();
}
});
This code will help you .
(int)dataSnapshot.getChildrenCount()
Im creating an app with Firebase database here is my data structure:
{
"teachers" : {
"USYSacnOjDR5EAPwljZMHtggN9I2" : {
"name" : {
"teacher_name" : "Alison"
},
"members": {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : true
}
}
},
"users" : {
"sIrfMA3bm0R9uj55nDUFpFyabcL2" : {
"position" : {
"bpos" : "0"
},
"name" : {
"email" : "m#m.com",
"name" : "John",
"surname" : "Clash"
}
}
So now in RecyclerView im trying to display all of the Alison teacher members, as you can see John Clash is set to true. Anyway when i try to retrieve user this way:
reference = FirebaseDatabase.getInstance().getReference("teachers").child(teacherkey).child("members");
reference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.add(user);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.remove(user);
adapter.notifyDataSetChanged();
}
the app crash because of NPE, datasnapshot key is valid, it is John's account key but value of snapshot is true. How can i solve that and get from John's data name and surname?
#Edit:
Here is my retrieving code:
public void updateList() {
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.getKey();
DatabaseReference userIdRef = FirebaseDatabase.getInstance().getReference().child("users").child(userId);
userIdRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.child("name").getValue(User.class);
result.add(user);
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) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
To solve this, you need to query your database twice. Please see the code below:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference membersRef = rootRef.child(teachers).child(teacherId).child("members");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String userId = ds.key();
DatabaseReference userIdRef = rootRef.child("users").child(userId);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
Log.d("TAG", user.getName());
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userIdRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
membersRef.addListenerForSingleValueEvent(valueEventListener);
You have 2 approaches to solve this issue:
a.) Inside onChildAdded you already have, if the value you got is true, do another search in database, but this time in "users" node. Something like
newReference = FirebaseDatabase.getInstance().getReference("users").child(dataSnapshot.getKey).child("name")
b.) In the "members" node, write "John Clash" instead of "true". This approach will work for now, but you will fall into the first approach if someday you need to retrieve email address as well
public void getFirstName(View view) {
Query newQuery = database.getReference("users").orderByChild("firstName");
newQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Iterable<DataSnapshot> iterator = dataSnapshot.getChildren();
for (DataSnapshot child : iterator) {
Friends friends = child.getValue(Friends.class);
Toast.makeText(DBActivity.this, friends.firstName, Toast.LENGTH_SHORT).show();
}
}
#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 am trying to retrieve the first names of all friends. When I try the above code for the mentioned JSON file structure, I am getting this error "Can't convert object of type java.lang.String to type com.example.seth.photopicker.Friends". Please help me with this issue.
Try this:
Query newQuery = database.getReference("users");
newQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
String fname=dataSnapshot.child("firstName").getValue().toString();
Toast.makeText(DBActivity.this, friends.firstName, Toast.LENGTH_SHORT).show();
}
}
The datasnapshot is at users and since you are using onChildAdded you do not need to iterate to be able to get the first name.
Query newQuery = database.getReference("users").orderByChild("firstName");
newQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
Friends friends = dataSnapshot1.getValue(Friends.class);
Toast.makeText(DBActivity.this, friends.firstName, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Equivalent code for above answer without using Child Listener.
I want to retrieve "7753400075_Canada_twinpalms_||_twinpalms_20170824001545_F5BA7F33AD51CE283332001BEC409A46" key, How to do so? Here is my code...
ref.addValueEventListener(new ValueEventListener() { //addListenerForSingleValueEvent
#Override
public void onCancelled(DatabaseError arg0) {
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Object response = dataSnapshot.getValue();
System.out.println("read data :"+response);
}
});
ref.child("chatmessage").child("devicetoken").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
// Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// System.out.println("previousChildName :"+previousChildName);
}
}
});
Here is the Firebase database example:
I tried using child data snapshot method but did not worked. It returns all data. But i need to get only the new child added parent. Any help for this will be much appreciated.
To solve this, you need to filter your results. Assuming that chatmessage is a direct child of your Firebase database root, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference deviceTokenRef = rootRef.child("chatmessage").child("devicetoken");
Query query = deviceTokenRef.orderByKey().limitToLast(1);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
Log.d("TAG", key);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(eventListener);
I've created AutoCompleteTextView for Ingredient, it works perfect. The DB save also works, I've tested it without validation.
If Ingredient exists in Firebase db I want to add recipe to DB.
For example if RecipeIngredients="milk" recipe should be saved to DB.
Here's my code.
DatabaseReference ingDBref = FirebaseDatabase.getInstance().getReference("Ingredients");
DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference("Recipes");
public void addRecipe(){
final String RecipeName=RecipeNameEditText.getText().toString();
final String RecipePrepareTime=PrepareTimeEditText.getText().toString();
final String RecipeIngredients=IngredientsACTV.getText().toString();
final String RecipeDescription=DescriptionEditText.getText().toString();
final String RecipeDifficulty=DifficultySpinner.getSelectedItem().toString();
key=databaseReference.push().getKey();
ingDBref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
if(data.child(RecipeIngredients).getValue()!=null){
Recipes recipes=new Recipes(key,RecipeName,RecipeDifficulty,RecipePrepareTime,RecipeIngredients,RecipeDescription);
databaseReference.child(key).setValue(recipes);
Toast.makeText(AddRecipeActivity.this,"Saved...",Toast.LENGTH_LONG).show();
}
else{
IngredientsACTV.setText("");
Toast.makeText(AddRecipeActivity.this,"Error...",Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Firebase DB
if(data.child("ingredientName").getValue().equals(RecipeIngredients))
Solved my problem.
This is happening because you are looping through the whole object. If the condition has been met, then you you set that value, if not then the else part is triggered for each of the remaining elements.
To solve this you can remove the else part if not needed or you need to use the exists() method provided by Firebase. To achieve this, just attach a listener on the same database reference and check if that child exists.
Hope it helps.
Try this
mDatabase.child("Ingredients")
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, String> map = (Map<String, String>) dataSnapshot.getValue();
String value=map.get("IngredientName");
// here will be your value of IngredientName
if(value.equals("Milk"){
// do something
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
myDialog.CancelProgressDialog();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
myDialog.CancelProgressDialog();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
myDialog.CancelProgressDialog();
}
#Override
public void onCancelled(DatabaseError databaseError) {
myDialog.CancelProgressDialog();
}
});