I have some difficulties building a query for selecting data in firebase database.
My database structure is like this:
I need to get all users which have contact ghopper. Here the result is alovelace and eclarke. But I really have no idea how to do this simple query in Java.
Thank you for your help!
You'd use Firebase Database queries for that:
DatabaseReference usersRef = FirebaseDatabase.getInstance().ref("users");
Query query = usersRef.orderByChild("contacts/ghopper").equalTo(true);
// My top posts by number of stars
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
System.out.println(snapshot.getKey());
}
}
But this requires that you define an index for each user, which doesn't scale. That is because the structure you have now is meant to allow to easily determine the users for a chat room, and you're trying the opposite.
To efficiently allow getting the chat rooms for a user, you should structure your data so that it also keep a list of users for each chat room. This is often called a secondary/reversed/inverted index.
For more examples of this see:
Firebase query if child of child contains a value
my answer on modeling many-to-many relationship in AskFirebase
Related
The SQL query that I want to apply is:
SELECT time FROM Appointment WHERE date = "3/15/2019" AND time = "9:00AM"
but I don't know how to translate it in Firebase. I am using Firebase in Android Studio. My goal here is to prevent date and time duplicate since the app that I'm developing is an online appointment.
Database:
Appointment
angelcrist
aptype: "Objective(Computerized)"
date: "3/15/2019"
name: "Hephep Horray"
time: "9:00AM"
miriammejia
aptype: "Objective(Computerized)"
date: "3/5/2019"
name: "Romz Ysmael"
time: "9:00AM"
There is no way you can do this with the Firebase realtime database. It does not have the capability to perform filtering on multiple conditions. If you have a SQL background, I can say that there are no "multiple where clauses" in Firebase. If you want to check for matches on multiple properties, you'll have to create a composite field as explained in my answer from the following post:
How to sort Firebase records by two fields (Android)
If you consider at some point to try using Cloud Firestore, please note it allows you to filter on multiple conditions. Chaning multiple whereTo calls are working perfectly fine.
First fetch your Appointment data for that particular date using below query, and loop through dataSnapshot childrens to check if you have the time available for that date.
reference.orderByChild('date').equalTo("<yourDate>")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snap: dataSnapshot.getChildren()) {
//Check for time here
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Database like this
Users
+oagnpangnangpadngn
+psdpgpsdnpgndpsngpndap
+pdgpjdpsgpdsjpgjpsdjpg
--letssupposemyfriendkey <----- I want this key
--name Ahsan
--email test#gmail.com
Now As you can see there is 2 child in each User.
I have already setup an on click button who get the email from layout when I input it in Edit Text. So mainly I want use that email I inputted to get User Key of that email .
e.g I inputted ----> test#gmail.com
Now how do I search users for this email and then get the key of user who has this email?
I am not Using Firestore or Cloud Functions, so if possible don't give me answers for that Im using Firebase Realtime Database in Android Studio using Java (Not Kotlin).
What you're trying to do requires the use of a database query. For example, here is how to find all users with a given ``email` value:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Users");
Query friendQuery = usersRef.orderByChild("email").equalTo("test#gmail.com");
friendQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot friendSnapshot: dataSnapshot.getChildren()) {
System.out.println(friendSnapshot.getKey()); // letssupposemyfriendkey
System.out.println(friendSnapshot.child("name").getValue(String.class)); // Ahsan
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I highly recommend spending some time in the Firebase documentation on sorting and filtering, taking the Firebase codelab for Android developers, and reading previous questions about Firebase queries.
Hello guys here is my firebase database:
I want to get list of all medicines with particular symptoms.
Here is my code i.e what i have done
public void initializeMedicineListener(String node,String type,String value){
mDatabase=mFirebaseInstance.getReference();
Query query = mDatabase.child("Medicine").child("symptoms").orderByChild("name").equalTo("Neck pain");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
medicineList=new ArrayList<Medicine>();
if (dataSnapshot.exists()) {
for (DataSnapshot medicine : dataSnapshot.getChildren()) {
Medicine data = medicine.getValue(Medicine.class);
medicineList .add(data);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
But i am getting null results.
Please guide me guys.Am i doing something wrong??
When you run a query at a location, Firebase check each child node at that location for the property that you order on and the range/condition you filter on.
mDatabase.child("Medicine").child("symptoms").orderByChild("name").equalTo("Neck pain");
So this checks the children of /Medicine/symptoms for their name property and only returns them if they have a value equal to Neck pain.
There are two problems with this:
Your JSON doesn't have a /Medicine/symptoms. Instead you have a Medicine, where each child node has a symptoms node.
Even if it did, your symptoms child doesn't have a value Neck pain. Instead you have an array, where each value may be Neck pain.
The closest you can now get to the query you want is:
mDatabase.child("Medicine").orderByChild("symptoms/0/name").equalTo("Neck pain");
This query returns medicines for which the first symptom name is equal to Neck pain. Firebase cannot perform a query across all array members to see if it contains a specific value in any position.
As usual with NoSQL databases: if you can't perform the use-case you want with your current data structure, you can typically change/expand your data structure to allow the use-case. And usually this is done by very directly mapping what you want to show on your screen to the structure in the database.
Your current data structures allows you to efficiently look up the symptoms (and other data) for a given medicine. That's great. It does however not allow you to efficiently look up the medicines for a given symptom. To allow that you can for example add a structure that maps each specific symptom back to its medicines:
symptoms
"Neck pain"
-L6hb2...bRb0: true
-L6rW...Fuxkf: true
With this additional structure (known as an inverted index or reverse index) you can now look up the medicines for Neck pain by simple loading /symptoms/Neck pain.
For more on this approach to categorization, see my answer here: Firebase query if child of child contains a value
You can't work with firebase database as relational databases .. instead of what you looking for .. you can create new node like this
medicineSymp
---neckpain
-------medicine1ID
-------medicine1ID
-------medicine1ID
this way you could get all medicines much faster and easier
I am developing an application, the application already registers new clients in Firebase. I was able to load the information from Firebase in RecyclerView using FirebaseUI, but I also need to put a search.
But I still have doubts about how best to do this, if anyone has any examples, it is always useful.
I was thinking of using the Retrofit, passing the link https://appname-f7ei5.firebase.com/clients to get JSON, does it work?
Or would I have to create a RecyclerView.Adapter and a ViewHolder, but how would I load the information directly from Firebase?
For the search, the best way is to use a getFilter() in the Adapter?
This is what i did for getting my Posts title on FireBase Database. Try to play with (child) and orderByChild and you'll see how it works. In another words, Imagine the child as the root in the head of the firebase database then collapse it and use orderByChild to get the under root items.
Query queryRef = mReference.child("posts").orderByChild("title").startAt(query).endAt(query + "\uf8ff");
queryRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChildren()) {
for (DataSnapshot postsSnapshot : dataSnapshot.getChildren()) {
final Post post = postsSnapshot.getValue(Post.class);
// and the rest ...
..
..
..
And in your case, It's gonna be :
Query queryRef = mReference.child("users").orderByChild("username").startAt(query).endAt(query + "\uf8ff");
This will return the user's usernames by your query search.
I saved the data into Fire base but when I retrieve it. The data is not in the sequence.
Here Data Is Saved In Accurate Sequence:
But when I retrieve data lost its sequence:
Here is my code for retrieving Data
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(" Value = "+dataSnapshot.toString());
}
(Printed it just to check values) Data is not in the sequence even I get it through
dataSnapshot.getvalue();
Hope so you got my question. I need the data in sequence
Firebase stores JSON data. By definition the children under a node in JSON are unordered. It is only when the data is displayed or retrieved that it gets an order. So the first screenshot that you show is just the order in which the Firebase Database console display it.
If you want to get the data in a specific order in your application, you need to do two things:
Execute a query that returns the data in that order.
Ensure that your code maintains that order.
The code you shared does neither 1 nor 2, so the order in which the data is printed is anybody's guess. Usually it will be in lexicographical order of the keys, but it is undefined.
To learn how to order/filter data, read the Firebase documentation on ordering and filtering. To learn how to maintain the order of items when you use a ValueEventListener, read the Firebase documentation on listening for value events. When you combine these two, you get:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
Query dataOrderedByKey = ref.orderByKey();
dataOrderedByKey.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println("Key = "+childSnapshot.getKey()+" Value = "+childSnapshot.toString());
}
}
...
This is an incredibly common mistake/question, so here are some previous questions for reference:
How to Convert Firebase data to Java Object...?
Ordering of data with Firebase Android
Firebase returning keys of child node in different orders on different devices/Android versions
How to sort by children key value in firebase?
Firebase .getvalue not in the same order as database
Order by date in negative timestamp is not working in Firebase