Can anyone please help? I'm stuck, can't retrieve simple data. This is my code:
And this is my database:
Assuming that the seller note, is a direct child of your database root, to get the value of your userType property, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userTypeRef = rootRef.child("seller").child(uid).child("BasicInfo").child("userType");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String userType = dataSnapshot.getValue(String.class);
Log.d("TAG", userType);
if(userType.equals("buyer")) {
//Your logic
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore errors!
}
};
userTypeRef.addListenerForSingleValueEvent(valueEventListener);
Please note that logic regarding the value you get from the database is placed inside the callback because Firebase API's are asynchronous. For more information, please also see my answer from the following post:
How to return DataSnapshot value as a result of a method?
Related
how can I extract all the "name" values contained in DATA?
I tried this to extract a single name but it doesn't work:
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("ALL");
Query query = myRef.orderByChild("name").equalTo("pluto");
Two problems:
The code you shared only declares a query. It doesn't read anything from Firebase yet.
You're trying to order/filter in a child property, but are not specifying the full path to that property.
The second one is easiest to fix:
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("ALL");
Query query = myRef.orderByChild("DATA/name").equalTo("pluto");
And then you can read the results with:
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
Log.i("Firebase", snapshot.getKey());
Log.i("Firebase", snapshot.child("name").getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
Thanks
I edited it so the log is working
Log.i("Firebase", snapshot.child("DATA/name").getValue(String.class));
If I want to print all the names, how should I do it?
I have a Firebase Realtime Database. I can write to the database without any problems however I can not read from it. I read on the docs that adding a ValueEventListener will trigger when attached and every time the data changes in the db. However, my onDataChanged Method never fires.
My code is shown below:
patientReference = databaseReference.child("patients")
patientReference.addValueEventListener(profileListener);
private ValueEventListener profileListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("In onDataChange");
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("inInCancelled");
}
};
Neither of the println get executed. Not sure what is going wrong but any help would be appreciated.
Thanks!
This is the Firebase database structure of my project.
I want to fetch complaint division, describe, stat for the particular hostelname and roomno. How to fetch these data and display in android project?
To get all those values, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference complaintsRef = rootRef.child("Complaints");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String complaintDivision = ds.child("complaintdivision").getValue(String.class);
//Get the other properties in the same way
Log.d(TAG, complaintDivision);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
complaintsRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be:
Plumber Related
This is a basic function in Firebase on Android. You can use ValueEventListeners with the database reference to do this.
The steps to achieve the desired results can be enlisted as below:
Create a Complaint model with the same fields as your database.
Get the right Firebase reference for your database node and add a ValueEventListener instance to listen for database changes.
Pass a DataSnapshot into the Complaint class and assign it to a Complaint object.
Do what you want with the Complaint object you have obtained.
Creating a Complaint class:
class Complaint {
// your fields should have the same name as database fields to prevent unnecessary complications
public String complaintdivision;
public String complaintid;
public String describe;
public String hostelname;
public String roomno;
public String stat;
public Complaint(){// required for Firebase
}
}
Getting the data from Firebase:
ArrayList<Complaint> myComplaintArrayList = new ArrayList<>();
FirebaseDatabase.getInstance().getReference().child("Complaints").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot complaint: dataSnapshot.getChildren()){
Complaint c = complaint.getValue(Complaint.class);
myComplaintArrayList.add(c);// you should have an ArrayList<Complaint> for this loop
}
// do what you want with the items you obtained
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
This is pretty much all of it. If you are still having problems, you should read a tutorial on Firebase.
So to fetch the data you would first declare a Firebase DatabaseReference object that points to your database:
private DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
You would then write a query using this object:
Query query = mDatabase.child("Complaints");
Now you attach a SingleValueEventListener to this query:
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Write a for-each loop to cycle through your node's children
for(DataSnapshot data: dataSnapshot.getChildren()){
//Create an instance of your model class to
//store the received data
//Make sure you have an empty constructor in your model class
Complaint complaint = data.getValue(Complaint.class);
//then simply call your getters on the complaint object
//to get what you need
complaint.getComplaintDivision();
complaint.getDescription();
//...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
To fetch more specifically, you just modify the query.
For more information on queries, see this
I get the Alex Mamo's Solution in order to check whether a unique value exists in my database but the snapshot gets always null. The solution is here:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("Users").child("Nick123");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
//create new user
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userNameRef.addListenerForSingleValueEvent(eventListener);
And my database looks like this:
users
(auto-generated push token ID)
fullname
username
gender
...
I don't know whether it's the right method but I used push() method for adding the user object to the database and this method generates push token ID like above.
So, in order not to create duplicate users, what should I change with the above solution? Is there a better method to do this? Maybe like checking the firebase uid with some firebase auth methods?
UPDATE
My database screenshot:
As you see the string just below 'users' is not the same as user's uid.
This is not the best practice when it comes to save user details into the database. First, you should implement Firebase Authentication and then in order to check if a user exist in your database, you should use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("users").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
//create new user
}
}
#Override
public void onCancelled(DatabaseError error) {
Log.d("TAG",error.getMessage()); //Don't ignore potential errors!
}
};
uidRef.addListenerForSingleValueEvent(eventListener);
So the key for solving this problem is to call the child() method and pass the UID as an argument instead of calling the push() method that generates an random unique identifier.
If you have this database:
users
(auto-generated push token ID)
fullname
username
gender
Then to check if user exists you need to do the following:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("users");
Query queries=userNameRef.orderByChild("fullname").equalTo("Nick123");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()) {
//create new user
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
queries.addListenerForSingleValueEvent(eventListener);
First if you have users lowercase letter, then inside child add users, then you need to use a query to be able to check if the fullname is equal to Nick123.
Usually the database is structured like this:
users
userId
fullname: Nick123
The attributes are key:value, the key is the identifier and Nick123 is the value, so inside the child() method you need to write the identifier which is fullname and not Nick123.
Then since you are able to get the userId, you can do this:
FirebaseUser currentFirebaseUser =FirebaseAuth.getInstance().getCurrentUser();
String userId=currentFirebaseUser.getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("users").child(uid).child("fullname");
userNameRef.addValueEventListener(new ValueEventListener(){...}
In my app, I need to check if a given element of my database on firebase has a child with a given name. I hoped it could be done by using something along the lines of:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
if (rootRef.childExists("name")) {
//run some code
}
I searched but I couldn't find anything useful.
Edit 2; worth putting on top: I think it is worth mentioning that this is actually downloading all data at this snapshot just to check whether any data exists. You should be mindful here. If the reference is huge (e.g. actually the root reference and not a specific child/property) then you should either find a deeper node you can use to check for existence or design your data structure differently so an efficient check is possible.
A database reference is effectively the URL for that data. You want to actually get data to see whether a child exists. This is why the method you seem to be looking for is on DataSnapshot.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
void onDataChange(DataSnapshot snapshot) {
if (snapshot.hasChild("name")) {
// run some code
}
}
});
Now, this design pattern feels a bit strange. You're reading the whole database just to see whether "name" exists. You can make this a bit more efficient by listening to rootRef.child("name") and then just checking whether snapshot.exists().
If you're trying to do validation here, and not control flow, you should consider putting this code in your rules.json.
edit: I originally used the wrong function name (childExists instead of hasChild)
Don't do like this
NEVER
It will take all your data and bring to device
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
void onDataChange(DataSnapshot snapshot) {
if (snapshot.hasChild("name")) {
// run some code
}
}
});
Check it by this way.
It will return the value of the child if exists, otherwise -> null
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("childName")
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
void onDataChange(DataSnapshot snapshot) {
if (snapshot.getValue() == null) {
// The child doesn't exist
}
}
});
A complete solution. No need to download all the data. Just check if the child exist like this:
// Assuming the names are in the name node. Remove "name/" if not
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("name/" + name);
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.exists()) {
// Exist! Do whatever.
} else {
// Don't exist! Do something.
}
}
#Override
public void onCancelled(DatabaseError error) {
// Failed, how to handle?
}
});
Try using .childexists in combination with .equalTo("Your specific name")
UsersRef = FirebaseDatabase.getInstance().getReference();
Users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if (snapshot.hasChild("childName")) {
// it exists!
}else{
// does not exist
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Use snapshot.exists() to check if the referenced database entry contains a child , irrespective of the value of the child.