Is there any way to listen firestore document change in aws lambda - google-cloud-firestore

I am looking for a way to listen firestore's document change in lambda function in aws, right now i can use firebases cloud function to listen document change on collection, but i want to listen these changes directly on lambda function

Related

How to deploy Firestore listener functions to GCP Cloud?

I'm using the following approach (source) to build a GCP Cloud Function that handles Firestore events.
const functions = require('firebase-functions');
exports.myFunction = functions.firestore
.document('my-collection/{docId}')
.onWrite((change, context) => { /* ... */ });
There is no example on how to deploy this correctly to GCP Functions though, only Firebase ones.
using the regular gcloud deploy commands such as this one won't work.
gcloud functions deploy FUNCTION_NAME \
--entry-point ENTRY_POINT \
--runtime RUNTIME \
--trigger-event "providers/cloud.firestore/eventTypes/document.write" \
--trigger-resource "projects/YOUR_PROJECT_ID/databases/(default)/documents/messages/{pushId}"
Any ideas on how to do this?
You can achieve the required effect with creating Cloud Firestore Trigger of your choice
For Cloud Functions (1st gen):
In the Trigger type field, select Cloud Firestore.
Select Event Type: Write
Mention the Document on which you want to trigger this function, eg.users/{doc_id}
Check Retry on failure Check box if you want to retry if it did not trigger
Click On Save
Modify your Function as per your requirement
Click Deploy
Make Modification on provided documented path, in our case users/{doc_id}
Check the logs for cloud functions. You will see the function got triggered.
For Cloud Functions (2nd gen):
Under HTTPS, in the Authentication field, select an option depending on whether you want to allow unauthenticated invocations of your function. By default, authentication is required.
Click on Add Eventarc Trigger (A modal will appear)
Choose Trigger Type : First Party
Choose Event Provider: Cloud Firestore
Event: google.firestore.v1.Firestore.Write
Resource : If you are having exact path for document choose Specific Resource else you want to target multiple documents using wildcard pattern
choose Path Pattern
Check Retry on failure Check box if you want to retry if it did not trigger
Click on Save Trigger
Click Next
Modify your Function as per your requirement
Click Deploy
Make modification on the targeted documents
Check the logs for cloud functions. You will see the function got triggered.

Firebase/cloud firestore: onSnapshot() vs on()

I have been using onSnapshot successfully to alert my code to changes in underlying data, as in
// Set up to listen for changes to the "figures" collection, that is,
// someone has created a new figure that we will want to list on the screen.
setFiguresListener: function () {
// `figuresCR` is a collection reference defined elsewhere
return this.figuresCR.onSnapshot((iFigs) => {
iFigs.forEach((fSnap) => {
const aFigure = figureConverter.fromFirestore(fSnap, null);
const dbid = aFigure.guts.dbid; // ID of the "figure" in the database
nos2.theFigures[dbid] = aFigure; // update the local copy of the data
});
nos2.ui.update();
console.log(` Listener gets ${iFigs.size} figures`);
});
But I now read about on in the docs. It explains:
[The on() function] Listens for data changes at a particular location.
This is the primary way to read data from a Database. Your callback
will be triggered for the initial data and again whenever the data
changes. Use off( )to stop receiving updates. See Retrieve Data on
the Web for more details.
The syntax is a bit different, and on() seems to do much the same as onSnapshot().
So what is the real difference? Should we be using on() instead of onSnapshot()?
on() is an operation for reading from Firebase Realtime Database. That's a completely different database with different APIs than Firestore. They have essentially no overlap. There is no on() operation with Firestore.
If you're working with Firestore, ignore all the documentation about Realtime Database, and stick to using onSnapshot() for getting realtime updates.
Other tyros who fall into this tar pit: in the API doc pages, you might think that since firestore is a database under firebase, you could look for help under firebase.database. But no: look only in the next section, firebase.firestore.

Golang mgo store Session or Collection

When my server starts up, it will create a connection to a mongo database, grab that *mgo.Session and store it in a "server" struct for handlers defined on that struct to use to serve requests.
I see two ways to actually execute this.
1) Save the `*mgo.Session` in the struct.
The upside of this is that you can call Session.Copy in each handler before using the session to have connection isolation. The downside is that you need to call .DB("x").C("y") for a specific x and y for each handler. If you wanted to change this, you need to find each instance where you're using it and change it. That's less than ideal.
2) Store the `*mgo.Database` or even `*mgo.Collection` object on the server struct.
The upside is that you can configure it in one place and use it. The downside is that there appears to be no way to use Copy() on the thing for connection isolation.
How do you recommend storing the mongo session so that you can cleanly use the connection and provide isolation between requests?

Firestore trigger temporal information

Hi so i understand firestore write triggers run out of order with respect to time. Is is possible to get timestamp information on when a write occured within the trigger functions execution context?
If you're using the Firebase CLI to deploy, every background function is delivered an EventContext object as its second parameter. You can use its timestamp property. Or, you can have the client write it into the document.
I assume something similar is available for the context object provided to code deployed by gcloud.

Change MongoDB Collection from local to server-side on running Meteor App

Due to the Meteor Docs there are 'server-side', 'client-side' and 'local' Collections. Is there a way to change the 'status' (e.g. if it's server-side, client-side or local) on a running app?
Use Case: A Web-Application where users can register and login. They can store sensible data. Depending on the Users personal preferences he should be able to choose if that data is stored local or on the server (General decision - not from case to case).
Current Approach: It's working fine if I either instantiate the Collection local CollectionName = new Mongo.Collection(null); or server side CollectionName = new Mongo.Collection('collectionName');.
But I can't think of an approach to make it possible to the user that he can change the Collection status.
Is there a way to do this?
Or is a workaround needed (e.g. Create both, a local and server-side Collaction, and just decide which to use for insert/update/find - what would mean a lot of duplicate code?!).
Edit: To make thinks clear: I want the user to be able to choose if his data is stored in a collection which is synced with the server or a collection without any syncing.
No, you can't change the type of a collection on a running app.
I think you are confused about what these terms mean. "Client-side" collections aren't permanently stored in localstorage. It just means it's a collection that's in the browser's memory. Just as "server-side" collections are those that reside in the server's memory. The difference is not how it's defined, but where the code runs. Most collections have a client-side and a server-side counterpart, and they are kept synchronized via pub/sub. Server-side collections are also synchronized with MongoDB (using the oplog).
Local collections can live in both places, but "local" means they aren't synchronized with anything.
I probably don't fully understand what you are trying to do, but local collections do not persist data.
If you pass null as the name, then you’re creating a local collection. It’s not synchronized anywhere; it’s just a local scratchpad that supports Mongo-style find, insert, update, and remove operations. (On both the client and the server, this scratchpad is implemented using Minimongo.)
This means any data added to them on the client will be blown away when the user closes their browser (unless you are also using one of the local collection persist meteor packages) and any data added to them on the server will be blown away when the meteor app is restarted. So I don't think you really want to use local collections.
Instead, I would use a regular collection (where a name is passed to the constructor) and either the standard allow or deny options (not really recommended anymore...but still a valid approach) or Meteor methods (the preferred approach) to control who can change data and what data is allowed to change.
Or, another option could be to pass your publication function a list of fields that the user wishes to see on the client for that given session. To do this you defined a new publication that receives a displayFields argument that you then use as the field specifier options in your collection .find().
Meteor.publish("userData", function (userId, displayFields) {
// validate the structure and contents of displayFields
// retrieve the data but only use the fields that the user requested
return UserData.find({user_id: userId}, {fields: displayFields});
});
Then on the client side you would subscribe to this and pass in the fields the user wishes to make visible on the client.
var displayFields = {
firstname: 1,
lastname: 0,
//...
};
this.subscribe("userData", [displayFields]);