New to firebase and trying to understand how things work. I have an android app and plan to use the offline support and I'm trying to figure out whether or not I need to use callbacks. When I make a call like:
productNode.child("price").setValue(product.price)
Does that call to setValue happen synchronously on the main thread and the sync to the cloud happens asynchronously? Or does both execute asynchronously on a background thread?
The Firebase client immediately updates its local copy of the data with the new value. As part of this it fires any local (value, child_*) events that are needed.
Sending of the data to the database happens on a separate thread. If you want to know when this has completed, you can register a CompletionListener.
If the server somehow cannot complete the write operation (typically because the write violates a security rule), the client will fire any additional events that are needed to get the app back into the correct state. So in the case of a value listener it will then fire a second value event with the previous value.
Related
Does that means that my callback will get updates every time data changes in the DB even on the server side as long as the sdk firestore client is alive?
To be more specific, your callback will be invoked for as long as the listener is added, and the process stays alive. You can expect the callback to get invoked when the results of the query change over time. From the documentation:
You can listen to a document with the onSnapshot() method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.
You should detach the listener to stop this effect as needed.
If realtime results is not what you want, use get() instead to fetch documents a single time.
If I do not use .off() in particular to shut down the event listener, will it be turned off automatically when the http request has been processed?
So when a user browses http://www.example.com/organisations and I retrieve the data with an .on() call like:
admin.database().ref('organisations').on('child_added', snap...)
What happens with that connection when the request is done and the user got his data? Since I don't close the event listener with .off() I should assume Cloud Functions is still listening to the child_added event? But on the other hand that wouldn't make any sense for an http-request, so I could also assume that Firebase closes all event listeners after the request has been processed?
If you don't call off() to stop a listener that was started by on(), it will not turn off. You may be billed for the bandwidth it consumes until the allocated server instance shuts down.
Use of on() in Cloud Functions is almost never the right thing to do.
You should probably just be calling once() at the location of your data and use it when it's ready.
are the realtime database trigger onWrite onCreate queued or threaded ?
Neither.
Cloud Functions events don't necessarily get handled in the same order that they occurred. If you are depending on ordering, your functions may not work the way you expect. There is no single ordered queue that all events pass through - this would not scale.
Each function invocation runs full isolation from other function invocations. Cloud Functions will spin up new server instances to handle load as needed. So, if one server is busy handling events, Cloud Functions may decide to add more servers to the mix to be able to handle more incoming events. Each server handles only one event at a time. The events are handled serially within each server instance, and handled in parallel between server instances. There is no "threading" going on, from the perspective of the event trigger code (that's not the way node.js works for application code).
I have an application where the web ui (react) Cloud Function then runs and updates a completion value in the database.
How can I show a 'progress' indication and take it down when the Cloud Function has completed?
I initially thought I would do something like this pseudo code with Promises:
return updateDatabaseToTriggerFunctionExec()
.then listenForFunctionDoneEvent()
.then return Promise.resolve();
However, I'm not sure how to know when the function has finished and updated a value. What is the recommended way to detect when a triggered Cloud Function has completed?
You'll have to implement something like a command-response model using the database as a relay where you push commands into a location and the function pushes results out that can be listened to by the client that issued the command. The thing that makes this work is the fact that the locations of the commands and responses and known between the client and server, and they have a common knowledge of the push id that was generated for the client command.
I go over this architecture a bit during my session at Google I/O 2017 where I build a turn-based game with Firebase.
An alternative is to use a HTTP function instead, which has a more clearly-defined request-response cycle.
I'm just getting started with Meteor and I have a REST API hooked up with publish / subscribe that can periodically update per client. How do I run this behavior once globally and only refresh as long as a client is connected?
My first use case is periodically refreshing content while clients are active. My second use case is having some kind of global lock to make sure a task is only happening once at a time. I'm trying to use Meteor to make a deployment UI and I only want 1 deployment to happen at once.
publish/subscribe will work automatically only when clients are connected. However, do not put any functionality that you want to control amount of execution times in publish or subscribe functions. They might run arbitrary amount of times.
If you want some command to be executed by any client use Meteor.methodss on server side, and call it explicitly with Meteor.call from client template event.
To make sure that only one deployment happens at any given time, simplest way would be to create another collection, called for example, CurrentDeployments.And any time deployment script function in Meteor.methods is executed, check with CurrentDeployments.findOne if there are ongoing deployment or not, and only call new one if none is running.
As a side bonus, subscribe to CurrentDeployments in client, to disable 'deploy' button in case one is already running.