Firebase Firestore query by document id using swift - swift

I am trying to query my database to get all the users where the document id is equal to the users id. I know that I can add that id as a field into the document, but I'd like to optimize the memory I take up, so I'd prefer accessing the document id directly through. Something like
.whereField(DOCUMENT_ID, isEqualTo, User.id)
DOCUMENT_ID is not a valid field so far as I know, and I don't know the equivalent. I have read around that other languages modules have a workaround like
.whereField(Firebase.firestore.FieldValues.documentId(), isEqualTo, User.id)
but I've heard hide nor hair of that in swiftUI. Any ideas?

To filter on the document ID in a query, you can use FieldPath.documentID() in Swift too: https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/FieldPath#/c:objc(cs)FIRFieldPath(cm)documentID. But if you do this in a single document, that'd be the same as just doing document(User.id).

Related

How to create a composite index in Firestore with document Id

So I'm using firebase cloud firestore with swift (but this is a general question with firestore), and I want to sort through some documents using a query, something like
fetchQ.whereField(fieldName, isGreaterThan: startingValue)
But then I want to guarantee some kind of order if the field has the same value, and it stands to reason that the document id is good for this, so I add
.order(by: FieldPath.documentID(), descending: false)
But now I get the error in the console where I have to paste the url in order to create a composite index. I do that, except it's only for the single index "fieldName", leaving out the document id, so obviously I get an error for trying to create a composite index with a single field. I also tried it with two fields plus the document id, and sure enough the url generates a composite index for the two fields but leaving out the document id.
The composite indexing page in the firebase console also does not have an option to create a composite index involving the document id.
So it would seem to me that maybe using document id for sorting is not the intended practice? Should I create a unique id for each document for sorting purposes or if I can use document id for ordering how should I do it?
From the docs: "By default, a query retrieves all documents that satisfy the query in ascending order by document ID" (firebase.google.com/docs/firestore/query-data/…). So the behaviour you want to to achieve is what you get out of the box.

Firestore: get an Observable doc from another field which is not the Id

I want to get a single Observable from a collection, but I want to get it from a different field that is not the id. It is possible?
I do not want to do a query and limit to 1. I need to get a Single Observable not an array Observable.
Schema:
Code:
this.afs.doc<Credit>('credits/uid/'+ uid).valueChanges();
Error:
Invalid document reference. Document references must have an even number of segments, but credits/uid/d1Zt8sozYqb6H27lhoJgF1Gx2Cc2 has 3
I am not sure if I understand correctly, but I guess that you want to get document with particular uid field value, not using document id.
This particular error is related with common feature of Firestore, that every document has to be in collection not in document. So path values for documents, (nested as well) are always checked, if the segments (devided by /) number is even ex. collection1/doc1/collection2/doc2/collection3/doc3
As results in your code we have 3 segments (like credits/uid/<uid_value>) so this is the error.
I am not very familiar with angularFire2 itself, but I have done it in JS. The approach is normally to query collection and than use method on the results, which in classic JS returns Query object on which the same methods can be used as on CollectionReference (which extends 'Query' btw - reference 1).
Combining this approach with those references: querying and collection I propose following solution:
this.afs.collection('credits', ref => ref.where('uid', '==', <uid_value>)).valueChanges()
If uid_value will be unique you should get your doc.
Unfortunately I do not have any playground to test the solution so please let me know how it works - or if there will be any additional errors.
I hope it will help! Good Luck!

Firestore: Order by sub-collection field

First of all, this is not a regular question. It's little complicated.
App summary
Recipes app where users can search recipes by selected ingredients (collection ingredients exists in firestore db). I want to store for every ingredient statistics how much did users search with that selected ingredient, so I can show them later at the top ingredients which they used mostly for searching recipes.
This is how my collection looks like:
http://prntscr.com/nlz062
And now I would like to order recipes by statistics that created logged in user.
first = firebaseHelper
.getDb()
.collection(Constants.INGREDIENTS_COLLECTION)
.orderBy("statistics." + firebaseHelper.getCurrentUser().getUid() + ".count")
.limit(25);
If logged in user hasn't yet searched recipes with ingredients, then it should order normally. Anyway the query above is not working. Is it possible this use case to be done with Firestore.
Note: Statistics may exists or may not for logged in user, it all depends on his search.
You can't query and documents by fields that don't immediately exist within the document. Or, in other words, you can't use fields documents within subcollections that are not in the named collection being queried.
As of today (using the latest Firestore client libraries), you could instead perform a collection group query to query all of the subcollections called "statistics" for their count field. However, that will still only get you the statictics documents. You would have to iterate those documents, parse the ingredient document ID out of its reference, and individually get() each one of those documents in order to display a UI.
The collection group query would look something like this in JavaScript:
firestore
.collectionGroup("statistics")
.where(FieldPath.documentId())
.orderBy("count")
.limit(25)
You should be able to iterate those results and get the related documents with no problem.

mongodb find documents with field from other collection

I have two collection on stores user data and another stores all invitations.
In invitation collection I only store two ids one is fromID and another is toID
I am able to get all the document array from invitations collection, but how to get the user detail from user collection.
Thanks
MongoDB isn't a relational database and isn't the best choice to store such data. That being said, you can use the $lookup function as part of an aggregate query. See the docs, here.
You can use populate to get user detail. that is assuming in your mongoose model you made the toID and fromID of type mongoose model and you set the correct ref. check the docs. http://mongoosejs.com/docs/populate.html

how to join a collection and sort it, while limiting results in MongoDB

lets say I have 2 collections wherein each document may look like this:
Collection 1:
target:
_id,
comments:
[
{ _id,
message,
full_name
},
...
]
Collection 2:
user:
_id,
full_name,
username
I am paging through comments via $slice, let's say I take the first 25 entries.
From these entries I need the according usernames, which I receive from the second collection. What I want is to get the comments sorted by their reference username. The problem is I can't add the username to the comments because they may change often and if so, I would need to update all target documents, where the old username was in.
I can only imagine one way to solve this. Read out the entire full_names and query them in the user collection. The result would be sortable but it is not paged and so it takes a lot of resources to do that with large documents.
Is there anything I am missing with this problem?
Thanks in advance
If comments are an embedded array, you will have to do work on the client side to sort the comments array unless you store it in sorted order. Your application requirements for username force you to either read out all of the usernames of the users who commented to do the sort, or to store the username in the comments and have (much) more difficult and expensive updates.
Sorting and pagination don't work unless you can return the documents in sorted order. You should consider a different schema where comments form a separate collection so that you can return them in sorted order and paginate them. Store the username in each comment to facilitate the sort on the MongoDB side. Depending on your application's usage pattern this might work better for you.
It also seems strange to sort on usernames and expect/allow usernames to change frequently. If you could drop these requirements it'd make your life easier :D