Query Document Based on Regex in Firestore [duplicate] - firebase

This question already has answers here:
Query over list in firebase
(2 answers)
Closed 2 years ago.
I want to query a document in Firestore using a regex. This is because in order to add a search functionality into my Flutter app, I need to be able to create a query based on the search. For example if the user types: 'alice' -- I would have a regex that would look like (?i)alice and I would query firestore for any documents that the name field meets this regex, whether it be Alice, Alice Doe, or Doe Alice. I'm looking for a query that would look something like this:
Firestore.instance.collection('people')
.where('name', matchesRegex: '(?i)alice')
Thanks for any help. I feel like this is a pretty basic feature but I can't find it any where in the docs. And I really can't get all of the documents and search based off of that because the collection is very large, and I don't want to read that many documents.

Firestore does not offer any regular expression in queries. Those types of queries do not scale in the way that Firestore requires. It only supports exact string matches, and range queries with string prefixes.
If you need more flexible text-based queries, consider mirroring your data to a text search engine, such as Algola, as describe in the documentation.

Related

Firestore: Is there a way to get all collection documents with their sub collection documents [duplicate]

This question already has answers here:
Firestore: Does querying a collection also includes their sub collection?
(2 answers)
Closed 3 years ago.
I have collection users which have a sub collection called "notes about". "Notes about" have security rules that only users with role - "manager" can access them. Now everything works nice and so on, but my problem starts when manager decides to update his name, surname or imageUrl.
Since all notes have also property called "addedBy" which contains user name, surname, id and imageUrl, I need to go through all users and all their notes about sub collection documents, so I can check each document and update it with cloud function.
So far looks like I will have to refactor my db and store "notes about" in a separate collection. But maybe there is a way to get all collection documents with all their sub collection documents in another (reasonable) way.
I would prefer not to refactor my DB but maybe that's the only solution at the moment.
What are your thoughts?
DB model:
But maybe there is a way to get all collection documents with all their sub collection documents in another (reasonable) way.
Unfortunately there isn't. Queries in Firestore are shallow, they only get items from the collection that the query is run against. There is no way to get documents from a top-level collection and other subcollections in a single query. Firestore doesn't support queries across different collections in one go. A single query may only use properties of documents in a single collection. IMO, you can go ahead by querying the database multiple times to get the desired values. Is not so slow as might think.
Another possible solution in your case might be to use collection group query. In order to use this new feature, all the subcollections shoould have the same name.
Now it's up to you to decide if you'll use more than one query to get the data, or use collection group query or even refactor the database to fit your needs.

Firestore - query all documents which field matches values in a list (like SQL IN)

I have a book collection for example, each book has 'genre' field. How to query all books which genre is "fantasy" or "historical"? Like SQL SELECT * FROM book WHERE genre in ("fantasy", "historical"). Pretty usual SQL query as my opinion.
I found this feature request in GitHub, which isn't resolved yet. The Firestore documentation says: "Logical OR queries aren't supported". So, I cannot do such simple query in Firestore? What is a workaround? Should I query each genre separately and join the result?
Note, that I found similar questions like "How to get multiple documents by set of ids?", but not about custom properties. For ids, there is 'getAll()' method in the js admin sdk for example.
It is not supported in firestore as you correctly identified. You can send two separate queries and merge the results locally. This is how it needs to be done unfortunately. If yours is a simple usecase, sending two separate requests shouldn't be a problem.
However, have a look at rxfire package which is officially supported by firebase. Note that it doesn't support or queries per se but with the help of rxjs, it makes such tasks easier to manage. Here's an excerpt from the link below on what it can do:
Firebase provides realtime streams and async callbacks to do all sorts
of awesome things in your app. Getting data from one realtime stream
is easy enough, but what if you want to join it from another?
Combining multiple async streams of data can get complex. At Firebase,
we wanted to help simplify things, so we created a new JavaScript
library: RxFire.
Link to introductory blogpost: RxFire

Firestore multiple querys on the same field [duplicate]

This question already has answers here:
Firestore multiple range query
(3 answers)
Closed 4 years ago.
We are building a app where we need to show nearby posts, made by users. A post should only be shown, if it is not more as 4 hours since posting. Because firestore doesn't provide geoquerys, i have to do a search, where all posts in a specific square are returned. This is my current query:
collection("posts")
.where("creation", isGreaterThan: DateTime.now().subtract(Duration(hours: 4)))
.where("location", isLessThan: cornor1OfSquare)
.where("location", isGreaterThan: cornor2OfSquare)
The problem with this query is, that it's not allowed to add multiple where statements filtering on different fields.
Filtering by one property locally and one on the server side is not possbile, because we have millions of posts in our app.
Is there any other way to do this? For example restructure the data on the server, to make queries like this possible? I researched, but only found solutions, with "simple" data. But i have a Timestamp and a GeoPoint field, which makes it more complex.
The second approach, which comes to my mind, is to use cloud functions, but i have no idea how to do that, and if it is the best solution available.
I am programming in Dart/Flutter.
The Cloud Firestore doesn't support range filters on different fields.
You most create separate query for each OR condition and merge the query results.
See this link for more: https://firebase.google.com/docs/firestore/query-data/queries?hl=en-us

Firestore sub collection querying data [duplicate]

This question already has answers here:
How to list subcollections in a Cloud Firestore document
(4 answers)
Closed 5 years ago.
I am reading the docs and see that FireStore allows sub-collection. Which is great. Consider the following example as mentioned here int he docs.
As shown in the docs I can get the reference to the last doc as follows
var messageRef = db.collection('rooms').doc('roomA')
.collection('messages').doc('message1');
In the above example, the id's for docs and collections are typed in.
There are cases when id's are dynamically generated. In such a case how can I know how many collections a doc has? Or whether a doc has any sub-collections. How can I do that?
On mobile clients, you can't know how many collections or what collections a document has. There is just no API for that. You have to know ahead of time what collections may exist for a document, or accept that a query on an unknown subcollection may return no documents.

Retrieve totally different keys from Firebase [duplicate]

This question already has an answer here:
firebase equivalent to sql where in ()
(1 answer)
Closed 5 years ago.
I use orderByKey for requesting data by keys from Firebase. I can get several objects if keys are similar — start or end with the same string.
But how can I retrieve totally different keys with one request to Firebase, e.g. "n:1-2-3" and "n:2-3-4"? I use equalTo, but can I specify more than one key there?
I know how to do it with different requests — one request per one key, but it's not optimal.
Currently firebase only supports one condition. Explained more in the below text:-
If lets say you have two keys that are a123 and a234 then to retrieve you can do this:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference();
ref.orderByKey().startAt("a").limitToLast(10).addValueEventListener(..){..}
The limitToLast() method is used to set a maximum number of children to be synced for a given callback
You can use limittolast or limittofirst, to limit the results that are obtained from the database.
Also currently firebase only supports one condition. So you cannot have more than one orderbykey or orderbychild or the two together..

Resources