I'm trying to implement a quote bookmarking service.
- Given a quote collection, it has four info - quote, userId, authorId and sourceId.
- Given an author collection, it has two info - name, userId
- Given a source collection, it has three info - name (Star Wars), type (book, film), userId
When a user tries to save a quote, I would like to have a transaction where I'll check if the author exists (query via name. if yes, return the authorId. if no, create an author). Same goes for the source + type. Both author and source will return their respective ids. During saving the quote, the quote object will be created with the authorId and sourceId.
Is such a case possible? I've check that within a Firestore.firestore().transaction, there is only getDocument function and I can't do a query using whereField().
I've read somewhere that, we can enforce the create via the rules, and throw an error or some sort in a try/catch where the catch block will do a getDocument?
In the case where I can't do a query within a transaction and I can only rely on getDocument, does that mean the author/source collection's Id, has to be a composite key like "userId + hash(author/source's name)"?
What's the advice on performing such an action? Or Firestore can't handle such a use case?
In summary, I'm trying to do this (in pseudo code)...
Firestore.transaction {
// Get or create author
let author = Author.getOrCreate("Yoda", userId)
// Get or create source
let source = Source.getOrCreate("Star Wars", "film", userId)
// Save quote
let quote = Quote.create({
quote: "Do or do not. There is no try",
authorId: author.id,
sourceId: source.id,
userId: userId
})
}