Here is my Firebase Realtime Database structure:
I want to retrieve each and every image in a child(images1,images2,images3,images4 are the child names)
private void loadmybanners1() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("BannerImages");
ref.orderByChild("images2").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
final String myImg1 = "" + ds.child("image").getValue();
try{
Picasso.get().load(myImg1).networkPolicy(NetworkPolicy.OFFLINE).into(ban2Iv, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError(Exception e) {
Picasso.get().load(myImg1).into(ban2Iv);
}
});
} catch (Exception e) {
ban2Iv.setImageResource(R.drawable.ic_image);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
I have used this code to retrieve the image2. But from that, I can only retrieve the images1 child data. What are the modifications to do?
I want to retrieve each and every image in a child
To get each and every child within your BannerImages node, there is no need to use a query, you can simply use a DatabaseReference, as in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference bannerImagesRef = rootRef.child("BannerImages");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String myImg1 = dataSnapshot.child("images1").child("image").getValue(String.class);
Picasso.get().load(myImg1)
String myImg2 = dataSnapshot.child("images2").child("image").getValue(String.class);
Picasso.get().load(myImg2)
//And so on for the other images3, images4, and images5 children
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
bannerImagesRef.addListenerForSingleValueEvent(valueEventListener);
Add this dependency
implementation 'com.github.bumptech.glide:glide:4.10.0'
After getting Url from Firebase.Just Use below line
Glide.with(context).load(Firbase Url).into(imageView);
Related
the maxid integer variable should have the value for the getChildrenCount() from the firebase database, but it seems that the addValueEventListener is not working.
The following is my java code from Android Studio:
#IgnoreExtraProperties
public class ProfileID_Generator extends AppCompatActivity {
public int maxid;
private int ProfileID;
private String value;
private final DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("User");
public ProfileID_Generator(){}
public int profileID_generate(){
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
maxid = (int) snapshot.getChildrenCount();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
ref.child(Integer.toString(maxid)).child("ProfileID").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
String val = snapshot.getValue(String.class);
value = val;
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
if(maxid==0){
ProfileID = 10001;
}
else{
ProfileID = Integer.parseInt(value)+1;
}
return ProfileID;
}
}
The following is the data from the realtime database from firebase:
All data is loaded from Firebase (and most cloud APIs) asynchronously, which changes the order in which code executes from what you may expect and be used to.
The problem is not that getChildrenCount isn't working, but that ref.child(Integer.toString(maxid)) is executed before maxid = (int) snapshot.getChildrenCount();. It's easiest to see this if you add some logging:
Log.i("Firebase", "Start loading maxid")
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
Log.i("Firebase", "Got data for maxid")
maxid = (int) snapshot.getChildrenCount();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
Log.i("Firebase", "Start loading ProfileID")
ref.child(Integer.toString(maxid)).child("ProfileID").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
String val = snapshot.getValue(String.class);
value = val;
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
When you run this code it logs:
Start loading maxId
Start loading ProfileID
Got data for maxid
This may not be the order in which you expected the output, but it is working as designed and explains perfectly why your code doesn't work: by the time you starting loading the ProfileID, the maxid isn't known yet.
The solution for this type of problem is always the same: any code that needs the data from the database has to be inside onDataChange, be called from there, or otherwise synchronized.
So the simplest fix is to move the code that loads the ProfileID into the onDataChange that sets maxid:
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
maxid = (int) snapshot.getChildrenCount();
ref.child(Integer.toString(maxid)).child("ProfileID").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
String val = snapshot.getValue(String.class);
value = val;
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
This is an incredibly common problem and stumbling block for developers that are new to asynchronous APIs, so I recommend reading up on some more questions about it, such as:
getContactsFromFirebase() method return an empty list
Setting Singleton property value in Firebase Listener
Not sure why, but with the code I have, I cannot seem to get the value of 'isOnline':
dolRef = DatabaseReference dolRef = FirebaseDatabase.getInstance().getReference("DriversOnline");
dolRef = dolRef.child("iosDriver");
dolRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String driverid = ds.getKey();
// get value of 'isOnline'
dolRef = dolRef.child(driverid);
Log.e(TAG, "dolRef: " + dolRef);
dolRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dss : dataSnapshot.getChildren()) {
String online = dss.child("isOnline").getValue(String.class);
Log.e(TAG, "Online: " + online);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Below is a part of my firebase db:
"DriversOnline" : {
"iosDriver" : {
"BruEGfToc8axIWJk1o01fxcwd8I2" : { // driverId
"isOnline" : "true",
"latitude" : 45.276,
"longitude" : -66.064
}
}
}
Any idea why I can't get the value of 'isOnline' other than null ?
I think you're nesting your listeners one level deeper than needed.
DatabaseReference iosRef = FirebaseDatabase.getInstance().getReference("DriversOnline/iosDriver");
iosRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot driverSnapshot: dataSnapshot.getChildren()) {
String driverid = driverSnapshot.getKey();
DataSnapshot isOnlineSnapshot = driverSnapshot.child("isOnline");
System.out.println(isOnlineSnapshot.getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
Some things to note:
Reassigning one generically named dolRef variable 4 times in a block of code like this is a code-smell. It makes it much harder to follow what's going on, and to check if the variable points to the right location. Give each of them a name that clearly indicates what they point to, as I've done above.
There is no need to attach a second listener, as the value of isOnline is right in the driverSnapshot. You can just request the child snapshot with the right name, and then the value from that.
Don't ignore error, as that hides potential problems. At the very least throw them, as I've done above.
driverid = FirebaseDatabase.getInstance().getReference("driver");//If there is another driver table, the path must be two layers.
driverid.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Driver driver = dataSnapshot.getValue(Driver.class);//class model
dolRef = FirebaseDatabase.getInstance().getReference("DriversOnline/iosDriver").child(driver.getDriverID);
dolRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DriversOnline driversOnline= dataSnapshot.getValue(DriversOnline .class);//class model
log.d("driverid","isOnline :"+driversOnline.getisOnline)
//display -> isOnline : true
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Firebase just silently don't get the data.
I work on it a lot of time but still don't really understand what is a problem.
Probably it's very simple mistake so get my excuses please
fRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
ids = dataSnapshot.child("dictionary").child("fruitIds").getValue(DictionaryIDs.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
DictionaryIds.class code
package com.example.asuper.mluvitslova;
import com.google.firebase.database.FirebaseDatabase;
import java.util.ArrayList;
public class DictionaryIDs {
private ArrayList<String> fruitIds = new ArrayList<>();
public DictionaryIDs() {
}
public DictionaryIDs(ArrayList<String> fruitIds) {
this.fruitIds = fruitIds;
}
public void addFruitId(String id){
fruitIds.add(id);
}
public ArrayList<String> getFruitIds(){
return fruitIds;
}
public void setFruitIds(ArrayList<String> fruitIds){
this.fruitIds = fruitIds;
}
}
And in log just NOTHING
This code must just get me the DictionaryIds.class file but in fact Firebase just get me null object.
Firebase database structure
Under the last fruitIds child, there are no DictionaryIDs objects, there are simple strings. To get all those ids, you need to loop through the DataSnapshot object using getChildren() method like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference fruitRef = rootRef.child("dictionary").child("fruitIds").child("fruitIds");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String id = ds.getValue(String.class);
Log.d(TAG, id);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
fruitRef.addListenerForSingleValueEvent(valueEventListener);
The result in your logcat will be all those ids.
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);
Here is my firebase data structure . The child "Tags" is a child of root.
final Query searchquery = mDatabase.child("Tags").orderByKey().limitToFirst(10).startAt(s.toString().toLowerCase()).endAt(s.toString().toLowerCase() + "\uf8ff");
searchquery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
try {
String u = dataSnapshot.child("article_name").getValue(String.class);
Toast.makeText(MainActivity.this,":/ : "+u.toString(),Toast.LENGTH_LONG).show();
}catch (Exception tg){
Toast.makeText(MainActivity.this,tg.toString(),Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I want to get the value of child "article_name" . I used the code above . But it is returning null .
Please use this code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference tagsRef = rootRef.child("Tags");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String article_name = ds.child("article_name").getValue(String.class);
Log.d("TAG", tagsRef);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
tagsRef.addListenerForSingleValueEvent(eventListener);
The output will be:
Blood Circulation
Dummy Article
Also don't forget to use names for the keys that does not contain any spaces. So you need to change blood circulation in blood_circulation or bloodCirculation