Currently the open sourced cloud function provided by Firebase/Stripe uses onwrite to Firebase database to trigger the charge to Stripe:
https://github.com/firebase/functions-samples/tree/master/stripe
It seems that it would be more direct and faster to just call Stripe using https trigger instead of writing to Firebase local database which syncs/writes to Firebase server database, which then triggers the cloud function call to Stripe.
Will there be any problems using Https call to trigger Stripe call? What advantages are there for using onwrite trigger instead of https?
Beginner to beginner, this is my understanding:
Let's say you have an app where a you need to
(1) sign users up for a subscription using Stripe, and then
(2) when users use the app, check to make sure their subscription is still valid.
For (1),
you'd only do this once(ish) per user, and you need to tell Stripe "make a new subscription for this user," so it makes sense to use an https.onRequest or https.onCall function.
For (2),
you'd be checking to see whether the user is subscribed many times, and you're not telling Stripe something, you're asking it about stored information: "is this user's subscription still valid?"
If you're asking about stored information, it's a lot faster to check your own database rather than to wait for a response from Stripe. You just need to make sure the information in your database (e.g. Firestore) is up to date with Stripe.
So what you can do is create a Stripe webhook that will trigger an https.onRequest function whenever there is a change to a user's subscription status. Then, your function writes the change to your database.
So, rather than ask Stripe over and over, "is this user subscribed," and wait for a slow response, you just check your own database, knowing that it's kept up to date by the Stripe webhook.
Related
I have a step in my new user flow where a user is registered with Firebase auth, and then a record is written to Firestore.
Is there a straightforward way to put both the user registration and the firebase write into a transaction, so if either one fails, they both fail?
Is there a straightforward way to put both the user registration and the firebase write into a transaction, so if either one fails, they both fail?
There are no Firebase products that support cross-product transactional operations. You'll have to nest both calls and always handle the errors. So do the authentication, and then write the data to Firestore or the Realtime Database.
A more convenient way of handling this situation would be to trigger a Cloud Functions in response to the creation of a Firebase user account. In this way, you will only need to handle a single operation on the client.
I am working on a project that, currently, is 100% Firebase. Ideally, given I'm fully Firebase, I'd like to stay with Firebase for a next task which is updating some of the records based on external API calls once per day.
I'm currently using Firebase Functions for triggered events, not using it for API calls, everything that happens in the functions is after a user does something, and doesn't respond back to any clients (only responds back to the database for updates).
Is Firestore Cloud Functions a good place to run something like this that could call an external API and then update as necessary? I saw the scheduled functions that require the Blaze plan, have considered it but not sure if there's another approach that's better built for this task.
Cloud Functions that trigger on Firestore events probably aren't what you're looking for. Firestore triggers only fire when something in your Cloud Firestore database has changed. That means you need something that's writing to some document in the database in order to get the code to run. Which means you need a way to schedule that operation.
No matter what kind of trigger you write, you will need to be on a billing plan in order to make external requests anyway. So even if you somehow managed to put together a solution that uses Firestore triggers, your project would still need to be on a billing plan.
This approach is perfectly okay - in fact, I am using the exact same approach in my project which has 100% Firebase back-end. The overall (Firebase) Cloud Functions gives flexibility in terms of invocation i.e. they can be invoked based on trigger (e.g. storage or database event) or can be called with the HTTP end-point. So, depending on your need you can either use Firestore trigger or database trigger or call an end-point.
Switching to Blaze plan is perfectly fine since otherwise we can't call an external end-point. I switched to Blaze plan just a few months back and didn't pay anything for that as my usage is within the free limit.
This question already has answers here:
Continue execution after sending response (Cloud Functions for Firebase)
(3 answers)
Closed 3 years ago.
I'm currently looking to take in a request (using Express/Firebase Cloud Functions)and do some calculations/make some requests, send a response, but then respond to a user before updating my database or doing some extra calculations.
Use case example: Occasionally, a user will follow another user. This means that I want to update all over my database so that my data is in the right place later on. I don't need my user to wait for me to do this, this is something I can do long after the server knows the user wishes to follow them.
Can I receive the user request, perform a server action, respond to the user, then continue on with my cloud function? I have read inn places that a function terminates on responses, but it's not clear how else you go about this or if it only terminates on specific responses.
The way to explain is not possible to achieve, I mean, after you return from a function the process is done.
However, there are several patterns you can implement, it just matters of playing with triggers, take a look.
You can save a state on a firestore collection and trigger a background function which fetches this state and do whatever you need.
If you don't feel like saving this on collection, you have PubSub available as well.
This should give you a good starting point to investigate what is the best solution for your use case.
Hope this helps!
There are two kinds of cloud Functions for Firebase: the ones that you can call directly (HTTPS Callable functions, HTTPS "simple" functions and scheduled functions) and the one that respond to events generated by some of the Firebase services or Google Cloud features like for example Firestore, Authentication events or Cloud Storage (see https://firebase.google.com/docs/functions for a full list)
Classically, when you want to send a response to a user after he/she initiated a Cloud Function, you would choose an HTTPS Callable functions or an HTTPS "simple" functions. But this is not the only way to do it: you can very well send a feedback to the user with a background triggered Cloud Function, mainly by writing something in Firestore (or the Realtime database) to a location the front-end is listening to.
With this second way, you can very well "respond to the user, then continue on with [the] cloud function". While with a callable Cloud Function when you send back the response to the user the Function is terminated.
So let's describe this method in a bit more details for Firestore:
You trigger the background function, for example by writing to a Firestore document/collection from your front-end
At the same time, from the front-end, you set a listener to a specific document (not necessarily the same document than above). See here for setting a listener.
The Cloud Function starts to do some work and at one moment writes to this specific document in Firestore
In the front-end, the user is informed of the write through the listener
In the background the Cloud Function can continue its other tasks.
The key point is that you have to correctly chain all the asynchronous tasks of the Cloud Function by chaining the promises.
I follow some guidelines to have my Vue.js state in sync with Firebase. I have set up references to Firebase and getters, mutations and actions in vue in a separate folder store. It seems to work when I update the states without Firebase connections (local) and it also works when I update Firebase from other components only using the Firebasereference and push - then the sync seems to work. My question is if I should update the state throw "action / mutation" and the mutation will do a push to the state array and in som magic way the Firebase will update which not happens in my case.
So - how to update? From the component using the reference, for example dbOrdersRef.push(order) or with a call to the store with for example this.$store.dispatch('setOrder', order) which don't updates Firebase (but other local variables updates).
I think scheme should be like this:
You should subscribe on firebase updates somehow (I'm not familiar with firebase but I'm sure that there should be some mechanism for that) and when updates come from firebase - you should mutate your store by dispatching some actions, to keep you store in sync with firebase.
Ideally, your app should work with your store only. Store should hide such implementation details as firebase usage. If tomorrow you will switch from firebase to something else, you shouldn't rewrite your components which work with the store. They still will work with the store and with the same actions.
When you update something in your store you need to update firebase as well. I think you can do it right in your actions, it should be fine. In that way, you can be sure that all changes which will appear in your store, will be in firebase. E.g. you call someAction which actually do some firebase manipulation. If you subscribed on firebase changes you won't even do something else in that action, except sending some command for firebase, because your subscription will update your store. Or you can mutate the store immediately (aka optimistic update), then wait for response from firebase, and then decide leave that update or call some mutation to rollback (however here you should be very careful because of subscription on firebase changes).
Or, alternatively, you can write some plugin for your store, which will send updates to firebase only when some change in your store has been done. In that case, updates from your app firstly will appear locally in your store, then your plugin will send them to firebase (maybe such plugin even already exist, idk).
I'm not an expert in firebase, but tried to share some thoughts about how it should work in general. Hope this helps.
Oh, back to your question:
dbOrdersRef.push(order) or with a call to the store with for example this.$store.dispatch('setOrder', order) which don't updates Firebase
I think you shouldn't use firebase in components at all and should use your store instead. So I'd rather advice to use the second option. But you should implement firebase updates by your own, there are no magic updates from store to firebase by default (at least if you aren't using some plugin with that magic).
Does anyone knows what the timing of the Firebase Cloud Functions onCreate Authentication Trigger is?
Is it like:
- User registers using SDK
- Firebase creates user in and for Firebase Authentication
- Firebase SDK sends login successful event
- Function onCreate is invoked
or like:
- User registers using SDK
- Firebase creates user in and for Firebase Authentication
- Firebase onCreate is invoked
- Firebase SDK sends login successful event
Or in other words:
Can I be sure that after a successful user registration a Firestore User Document was already created by a short Firebase Cloud Function script?
So can I be sure that when the SDK send the authentication successful callback that the Firestore user document was created?
You are given no guarantees about the timing of the delivery of events to your Cloud Function code. Of course, the system is going to try to deliver as fast as possible. But the fact of the matter is that there can be unpredictable delays at every stage through the processing of that event, so you shouldn't depend on any sort of specific timing. This is especially true when also dealing with other systems that work asynchronously as well, including Firestore (it sounds like you're implying that your function creates a document to read back later in the app).
The good news is that you can listen to the document that you expect to be created for the user, and receive it whenever it's ready.
As Doug has said, sadly there are no guarantees onCreate will be evoked in time, but here is my thought solution.
Because the onCreate hook can only access the auth user information, you will have to have a post-creation function. So I see two options:
it's worth having the post-creation function handle the case if the db record isn't created by the onCreate hook
OR
Don't even use the onCreate hook since it's almost redundant.