I've been trying to find a query for almost 2 days now
I want to search id (current user id) from the document 4 fields (customer1,customer2,customer3,customer4)
Here is the firestore document picture
tried this query
final Query userQuery = collectionReference
.whereEqualTo("customer1",firebaseAuth.getInstance().getCurrentUser().getUid())
.whereEqualTo("customer2",firebaseAuth.getInstance().getCurrentUser().getUid())
.whereEqualTo("customer3",firebaseAuth.getInstance().getCurrentUser().getUid())
.whereEqualTo("customer4",firebaseAuth.getInstance().getCurrentUser().getUid());
but this only shows up if the current ID is present in all 4. Is there any easier way to do this.
You can do that by using a field that is an array containing the uids you want to test, and then applying array-contains on it. In your case:
In your case:
customer: [customer1, customer2, customer3, customer4]
collectionReference
.where("customer ", "array-contains", firebaseAuth.getInstance().getCurrentUser().getUid())
Firestore does not support logical OR queries among mulitple fields. So, what you're trying to do is not possible with a single query using the database structure you have now. You would have to perform multiple queries and merge the results in the client.
If you want to be able to use a single query, you will have to change your database. One option is to put all the customers into a single array field and use an array-contains query to find a customer in that field.
Related
I am trying to display images from Firebase's storage in my Android app inside a GridView.
I have done that, however, the images are displaying in an unknown order, and I have noticed that there is a 'Last modified' column inside Firebase's storage when I upload the images to it.
My question is: is there a way that I could sort the images inside the GridView in order to display them according to that date? (for example, the last one added, would have the latest 'Last modified' date and would be viewed first and such...)
This is my code:
val listRef : StorageReference = FirebaseStorage.getInstance().reference.child("images/posts/$userName")
val fileNameList: ArrayList<String> = ArrayList<String>()
listRef.listAll()
.addOnSuccessListener { it ->
it.items.forEach{
fileNameList.add(it.name)
}
gridView?.adapter = ImageRecyclerAdapter(activity, fileNameList,userName)
}
Note: the code is in Kotlin
I have looked everywhere and couldn't find anything that helps.
Any help is appreciated, thank you :)
According to the official documentation regarding StorageReference's listAll() method:
List all items (files) and prefixes (folders) under this StorageReference.
You might not be interested in listing folders within the reference you are pointing to.
That been said, the best option that you have is to store the URLs in a database. Such a database can be either Cloud Firestore or Firebase Realtime Database. This means that each object should have at least two fields, one for the actual URL and one for a timestamp. Please see in my answer from the following post how you can add a timestamp to Firestore:
ServerTimestamp is always null on Firebase Firestore
Is in Java, but you can simply convert it to Kotlin. Once you have all URLs in place, you can create a query and order the URLs according to the date. In Firebase Realtime Database the default order is ASCENDING, but below is how you can reverse the order:
How to arrange firebase database data in ascending or descending order?
While in Firestore, you can simply pass the desired direction to Query's orderBy(String field, Query.Direction direction) method.
In firestore I have some sub-collections inside each collection just like below:
Collection1 -> id -> Sub-collection -> scId -> Data
So here I want to get all data from sub-collections by the help of the where clause. I tried one query like the below which is failing.
db.collection("Collection1").whereEqualTo("eDate", selectedDate)
.get().addOnSuccessListener(queryDocumentSnapshots -> {
List<Exp> mData = queryDocumentSnapshots.toObjects(Exp.class);
Here eDate is coming under the Data which is inside each sub-collection.
So is there any way to do that or any suggestions on how to do that or about the mistakes which I did here?
Firestore queries are shallow and do not extend above or below the named collection being queried. The query you show here will only return documents immediately within "Collection1". It will not consider any documents in nested subcollections.
If you want documents in a subcollection, you will have to build a CollectionReference to that subcollection, and query it individually. You can't query all subcollection nested under a document at the same time. You can't query across differently-named subcollections at the same time.
If this behavior does not meet the needs of your app, you should consider restructuring your data to do so, or building your app to perform as many queries as needed to get all the documents from among all the collections where they live.
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 have a users collection with uId, name, photo
I have a visits collection with uId, userId, location
I have a recyclerview in which I want to show the location with the user name and photo
Can I use the reference field type? If so, how will Firestore know to link visits.userId == users.uId ?
Maybe I first need to query all the visits and then query the relevant user but 2 things:
It means querying a lot of times.
I didn't understand how to collect the joined collection into the adapter, which is based on one query?
Please advice
Thanks
current code
visitsList = db.collection("visitsList");
Query query = visitsList.whereEqualTo("userId",prefs.getString("id","")).orderBy("visitDate", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AVisit> options = new FirestoreRecyclerOptions.Builder<AVisit>().setQuery(query, AVisit.class).build();
adapter = new VisitsListAdapter(options, VisitsListActivity.this);
RecyclerView rv = findViewById(R.id.rvVisitsList);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(adapter);
The code is a simple query from the collection, not sure how to get the name and photo from the userId field in that collection.
Can I use the reference field type?
Yes, you can use a reference field.
If so, how will Firestore know to link visits.userId == users.uId ?
Firestore results always comes from a single collection (at the moment). It does not automatically join the document from the users collection when you're reading from the visits collection. You will have to do this yourself.
That indeed means you'll be executing multiple reads, but it's often not nearly as slow as you may think. See Google Firestore - how to get document by multiple ids in one round trip?
Update: To show data from the user profile in a list of visits, there are two main options:
load the additional user document in populateView or with a custom parseSnapshot implementation.
duplicate the relevant user data in the visits collection (which is quite normal in NoSQL databases). Also see Alex' answer here: indexed query with FirestoreRecyclerAdapter.
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