I want to create an application that any user can add an advert (announce) with something that he wants to sell.
This is the structure of the Real-time Database in Firebase:
- advert
- category
- {uid}
- title
- price
- description
- location
I want to let the user to filter the adverts by category, title, and price.
Currently, I can filter the adverts only by title like this:
FirebaseDatabase.getInstance().getReference()
.child("adverts")
.orderByChild("title")
.startAt("tv")
.limitToFirst(20)
I have 3 questions:
How can i add more "and clauses"? Or how should i structure the nodes to filter more values?
How should I sort the values that i receive from the server in ascending order or descending order depending on uid?
Seems that the method startAt("abc") is not fetching only the children that has contains in the title "tv". Am i doing something wrong? How should I fetch only the children that contains the string "tv"?
On firebase, there is no way to add "AND clauses". You must structure your data in a way that matches your filtering needs.
I believe firebase already sorts the data by uid.
If you want to fetch only the children that contains the string "tv", you should use this query:
FirebaseDatabase.getInstance().getReference().child("adverts").orderByChild("title").startAt("tv").endAt("tv").limitToFirst(20);
I suggest that you watch the Firebase Database for SQL Developers Series. It has the answers for the 3 of your questions
Related
So suppose I am building an app that lets users manage trips. When a trip is created , any number of users can be added in it. I want this data to be stored in a single place and then for each user be able to retrieve the trips that that person is included in. My data looks like this:
-trips
-<trip-id>
-title
-budget
-etc
-people
-<person-id>
-name
-uid
-<person-id>
-name
-uid
-<trip-id>
-
-
-
This trip will contain all the trips created by all the users. To show any person their trips, I want to retrieve only the lists that person exists in.
This is what I've tried to do including other similar approaches.
rootReference.child("trips").orderByChild("uid").equalTo(FirebaseAuth.instance.currentUser.uid).addValueEventListener(object:ValueEventListener){
override fun onDataChange(snapshot: DataSnapshot) {
//this should only return the trips that current user exists in.
}
}
I have checked the documentation for searching and filtering on firebase but there is nothing that show filtering based nested keys. One particular example is this. I understand it perfectly. If for example I try to filter my trips based on the main attributes like title, budget, it works, but not when I use an attribute of a nested child.
What other approach can I use to filter based to nested keys or should I structure the data differently? Any help is greatly appreciated.
Firebase Realtime Database queries operate on a flat list of child nodes directly under the path that you query.
So the value you order/filter on has to be at a fixex path under each immediate child node. Since that isn't the case for your uid, you can't query across all trips for the UID of all users of those trips.
You can query across one trip for a UID of a user (and then get back that user), or you can query across all trips for properties of the trip itself, such as its title or budget.
If you want to query across all users on all trips, consider keeping an additional list where you have the UID of the user as the key, and then all their trips under there:
"user_trips": {
"uid1": {
"tripid1": true,
"tripid2": true
},
"uid2": {
"tripid2": true,
"tripid3": true
}
}
Also see:
Firebase Query Double Nested
Firebase query if child of child contains a value
Many to Many relationship in Firebase
Goal: show the list of groups based upon the recent message and when a new message comes, update the chat group list.
Firebase Structure:
Left one structure represents user model: Basically under student key, there is a list of the student then its details along with group ids in which he/she participated.
Right one structure represents the group detail model: Under chat_group key, there is a list of groups with details and also recent message timing.
Solution Tried:
Fetch the group id from the student using the onChildAdded method of firebase DB one by one then fetch its group details using the addListenerForSingleValueEvent method, then store in the list and every time sort it using sort method of array list and then call notifyDataSetChanged method of recyclerview adapter.
Problem with this approach: Too time-consuming and as the number of groups increases processing time also increases.
I think the best solution is to add a new key to the group details model for the students signed up , like that
SignedStudents : "student1 , student2 , student3"
Then you will read data from chat_group directly orderedByChild("recent_message_timeStamp") , then you have to filter it locally to get the groups only related to the specific student to add it to your list like that
String students = model.getStudents();
if (students.contains("student1")) addGroupToYourList();
This question already has an answer here:
Firebase query if child of child contains a value
(1 answer)
Closed 3 years ago.
I need a firebase query to filter the list based on the value of an array.
if any of the index of GID(Array) contains the given key. e.g my key is YsGMyfLSGRNHxDWQmhpuPRqtxlq1 and one node's GID have that on 0th index and other have that on 1st index. So these two lists need to be returned.
Currently, I can only get the one at 0th index using the code
//userID = YsGMyfLSGRNHxDWQmhpuPRqtxlq1
firebaseDatabase.child("Groups").queryOrdered(byChild: "GID/0").queryEqual(toValue:userID)
When I try to combine the query I am getting errors.
I don't know about your database structure, But I can explain that There is a limitation in Firebase Realtime database that you can only order by 1 child.
So now if we require to order by 2 Childs we can combine 2 nodes and make it 1 node and can apply order by query on it. For example
If we have username & email fields we can make a new field username_email and can apply order by on it.
Like
user: {
username: "john",
email: "john#g.com"
username_email = "john_john#g.com"
}
Now we can write
firebaseDatabase.child("user").queryOrdered(byChild: "username_email").queryEqual(toValue: "john_john#g.com");
There is no way you can filter your groups based on a value that exist within an array. If you want to query your database to get all groups a particular user is apart of, then you should consider augmenting your data structure to allow a reverse lookup. This means that you should add under each user object the groups in which that user is present.
This means that you'll need to duplicate some data, but this is not a problem when it comes to Firebase. This is a quite common practice, which is named denormalization and for that, I recommend you see this video, Denormalization is normal with the Firebase Database.
When you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.
However, what you need is actually allowed in Cloud Firestore. Its array-contains operator allow you to filter documents that have a certain value in an array. For more on this topic, please see the following post:
Better Arrays in Cloud Firestore.
I would like to perform wildcard queries on a Firebase database,
and do not know whether the libraries support this. - (my guess it does not.)
I want an optimal solution where the network traffic will be as little as possible, assume the dataset is millions of records.
Dataset (using prefix wildcard):
user_id:
id_001123:
name: "java"
id_002124:
name: "objective-c"
id_003125:
name: "swift"
How would the code look like to retrieve the record id_002124 name field using a wildcard, you only have a portion of the id. eg. "%124".
The expected result would be id_002124, and the name being "objective-c"
Any mobile language example code would great.
(Objective-C/Swift/Java)
Firebase Database queries can order/filter data based on the object's keys (e.g. id_001123), their values (doesn't apply in your case), or the value of a child property (e.g. the fact that name = "java").
For each of these Firebase can match items that have a specific value you specify, items starting at a value you specify, or items ending at a value you specify.
So you can create a query matching the item named objective-c with:
ref.child("user_id").orderByChild("name").equalTo("objective-c")
Or you can create a query matching id_001124 and id_001125 with:
ref.child("user_id").orderByKey().startAt("id_001125")
Or simply getting all items starting with id_0011:
ref.child("user_id").orderByKey().startAt("id_0011")
Or you can create a query matching id_001123 and id_001124 with:
ref.child("user_id").orderByKey().endAt("id_001124")
Firebase Database cannot filter based on the end of a value. So there is no way in your current data structure to get all items whose key ends in a 4.
Please read more about Firebase Database queries here: https://firebase.google.com/docs/database/android/lists-of-data#sorting_and_filtering_data
And see some of the many previous questions about searching for FirebaseL
How to perform sql "LIKE" operation on firebase?
Firebase query - Find item with child that contains string
Firebase "like" search on string
I have a problem to solve in my Android app. I currently retrieve from the Firebase Realtime Database a list of users to be displayed, these users having name and nickname. The name field is required and will always exist in the database, but the nickname is optional and may not exist. I need to display in alphabetical order so that the list is sorted by nickname and if it does not exist the name will be displayed, both ordered in the recyclerView. I have already made the filter to display the nickname in the list item if it exists, if it does not exist it will display the name, but I need to sort this list in the way I have described. For example:
Users
|-id1
|-name: "John Lande"
|-nickname: "Potato"
|-id2
|-name: "Ingrid Cage"
|-id3
|-name: "Anny Baratheon"
|-nickname: "Noisy"
And it should be displayed in the list like this:
- List
|- Ingrid Cage
|- Noisy
|- Potato
Remembering that the display of the names I have already resolved, but the ordination that I do not know how to do. In the firebase documentation I have already seen that ordering through the "orderByChild" should only be done for one value per query.