Closed bpkennedy closed 5 years ago
Modified hooks are ONLY triggered on a change on your server and NOT when that change was invoked from your front end. Eg. A change in Firestore console or another client with your same app.
Can you try and manually making a change in Firestore console in the browser and confirm if the hook fires or not?
Sent with GitHawk
Ah, that would make sense. I will try that over my lunch in about 6 hours.
If that turns out to be the issue, I'll consider this ticket resolved, but would then have a separate question on how to wait until a module's local change has fully propagated to firestore before running a follow up action in a different module.
Indeed, modifiedHook is called when the change is not from my client. Sweet! Can you suggest anything for the use case of the client needing to wait until the server is updated?
No, currently there is no feedback on this in my library. I believe that there are almost no use cases where this is needed.
Please tell me more about your use case and why you need this. Maybe I can teach you a work around for your case or add the functionality to my library if your use case in common enough.
Sent with GitHawk
I seem to be having trouble remembering the use case I had! I'd say that means it's not that important. š . If I come up to it in the future I can re-open this or open a new and describe for you/I/others to discuss and figure out if it's worth any effort to change. Cool?
Great!
I'll close this issue, but anyone with similar requirements, let me know down below!
Hi @mesqueeb, I think I have a use case for this. Although I am pretty new, so I might be missing something.
In Firebase I have a 'boards' collection, and each board doc has a number of subcollections.
The owner/editor permissions are on each board doc, and all the subcollections rely on this board existing in firebase so they can do permissions checks against it (I can't use permissions wildcards). The permissions setup is pretty similar to this, (where comments permissions references the story parent doc permissions).
When I create a new board this.$store.dispatch('boards/set', newBoard)
I want to ensure that the board exists on firebase before running openDBChannel
on all the subcollections (which triggers the permissions checks on the subCollections in firebase, which causes errors if the parent board doesn't yet exist to check for ownership).
I was hoping to use hooks or something to wait for the board to be created in firebase, before running the openDBChannel
's on the subCollections. Does this make sense? My two thoughts of how to approach this at the moment is to either poll for the board doc's existence (messy), or try and work out how to insert some sort of callback into your code based on where your code loads the log 'Initial doc successfully inserted' Happy to buy you many coffees if you have any idea how to approach around this!
:smile:
Hi @RichardCr ! Thanks for your detailed use case explained to me. It's already pretty late where I am, and I have an early day tomorrow: driving school š But I will ponder how to approach this and then I'll write up an answer hopefully tomorrow evening.
I already have some ideas it my head but as I said, it's kinda late and I wanna go over you post thoroughly again tomorrow š
Sent with GitHawk
No Problem! Any help at any time is amazing!
@RichardCr I had another look at the docs, and there are a couple of options. You'll have to determine which fits best in your app. š
If the doc already exists make it throw an error. Catch this error in the client and you know for sure you can open the DBChannels. If the document doesn't exist you can create it in the transaction and when this transaction succeeds you'll also know for sure you can open the DBChannels.
(one drawback: "Transactions will fail when the client is offline.") ā However, you could argue, when the user is offline, and there's no cache of existing docs, how can your security rules work in that case?
dispatch('boards/set', newBoard)
call, but include a Firestore Server Timestamp field. Server timestamps are only resolved on the server, so once this happens your server will trigger a "modification" which is sent back to your client.Therefore if you have your DBChannel open on boards
it will trigger the server hooks. (Either the serverChange.addedHook
or serverChange.modifiedHook
)
--
See what fits best in your application š I guess the conclusion is: try not to limit yourself by using ONLY methods from my library. See my library as "complementary" to the Firestore SDK, so always think if there's a good solution with their native functions.
--
Vuex Easy Firestore was made with ā„ by Luca Ban.
If this library helped you in any way you can support me by buying me a cup of coffee. āļø
You can also reach out on twitter if you want a one-on-one coding review/lesson. š¦
Thanks @mesqueeb !
I ended up just using db.collection().doc().set().then()
and then redundantly running dispatch('boards/set', newBoard)
inside then() to populate the local store, and all the other goodness your library does. This approach also let me set a loading spinner which was nice :) I then opened all the DBChannels in mounted() on the board component (opened by goToBoard()
) once I arrived on the new Board. Code below if anyone is interested.
async newBoard (event, template = false) {
// get a new board object and a unique ID ready
let newBoard = this.instantiateBoard(template)
const id = newBoard.id
// get a firebase reference for the new board
var db = Firebase.firestore()
let idDocRef = db.collection('boards').doc(id)
// start loading screen and set the new board
this.loading= true
await idDocRef.set(newBoard)
.then((success) => {
// once new board exists in firebase, use Vuex easy firestore to set it locally, and goto the board
this.$store.dispatch('boards/set', newBoard)
this.loading = false
this.goToBoard('', id)})
.catch((error) => {console.log(error)})
},
@mesqueeb Also is there a way to sponsor this repo? I keep trying to buy you coffees but for some reason my bank keeps blocking the transaction as suspicious and the wait time to talk to a human to fix this is the better part of an hour :/
@RichardCr thank you so much for offering. Please wait a few hours while I try to set up GitHub sponsor on my account. š
Sent with GitHawk
@RichardCr you seem to be calling Firestore's API twice, doesn't it bother you to be charged twice?
@RichardCr @louisameline is right about this:
using db.collection().doc().set().then() and then redundantly running dispatch('boards/set', newBoard) inside then() to populate the local store
to prevent calling the firebase api twice you can do this instead:
const newDoc = {}
const id = newBoard.id
db.collection('your/collection/path').doc(id).set(newDoc).then(() => {
this.$store.commit('yourModule/INSERT_DOC', {...newDoc, id})
})
See the source code for INSERT_DOC.
!! Please be careful with the promise from doc().set()
, because this will NOT be triggered when the user is offline. so you need to check for network connectivity before you call this.
BTW, I subscribed to Github Sponsors, and my profile is now "under review":
Nice! Thanks for submitting your profile. Our team will review it and get back to you within 7-10 business days.
I'll let you know when you can support me ;)
@RichardCr i'm so excited that I got accepted for Github Sponsors ! š You can see my profile here: https://github.com/sponsors/mesqueeb
I highly appreciate your support and it enables me to work harder on vuex-easy-firestore. I got big plans for the future improving many aspects based on everything I learned these past two years!!! š„š„š„
@louisameline @mesqueeb. Thank you both. I was being somewhat lazy to get it all working. Now that it is, i'll be making these changes on the long journey to production. @mesqueeb congrats on being accepted. It is a worthy repo. I started sponsorship :) If I manage to release and monetise my current project I'll move up a sponsorship tier :D
@RichardCr Thank you so much for your support!! š You're my first supporter šššš
Feel free to open more issues whenever you're stuck.
Heya! So, I'm at a point where one vuex module needs to know when an item has changed on the server and then ask another vuex module to do some work. I am trying to use the
modifiedHook
but it doesn't seem to fire or register a "modified" trigger for me. My current, hacky workaround:But I know this is either a misunderstanding on my part or maybe a bug? The module I want to listen to (
users
) is a 'collection' - I've tried adding a modifiedHook like so:And in the other module (at path
users/{userId}
) which is a 'doc' type, I try making the patch that I thought should trigger the server change inusers
collection:I have verified in Firestore that the data is getting changed as I would expect - just the modifiedHook never prints that console.log.