Failure to Deploy Cloud Function When Using Wildcard in Trigger - javascript

I'm trying to deploy a cloud function that will trigger whenever a document is added to a particular collection as below:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const Firestore = require("#google-cloud/firestore");
const firestore = new Firestore({ projectId: config.projectId });
admin.initializeApp(config);
exports.checkCapacity = functions.firestore.document("gran_canaria/las_palmas_1/miller_pendientes/{albnum}")
.onCreate(async (snapshot, context) => {});
However this throws the Deployment failure error:
Failed to configure trigger providers/cloud.firestore/eventTypes/document.create#firestore.googleapis.com (gcf.us-central1.checkCapacity)
The error clears if I remove the wildcard and change the reference to:
"gran_canaria/las_palmas_1/miller_pendientes/albnum"
I've attempted changing the method to onWrite(), deleting and re-deploying the function and checking the cloud status at https://status.cloud.google.com/ but can't find any solutions.

I have been able to deploy successfully a Cloud Function with a trigger on an onCreate event on my Cloud Firestore.
I have been successful by imply using the provided template in the Console UI when creating the Cloud with the following:
The index.js used is the sample provided by GCP when created the function, which simply prints to the logs which document triggered the change.
Looking at the documentation in Firestore, I see that you probably used the samples provided there, so maybe using the above settings will make it work for you.

Related

How can I invoke a firebase storage function locally and manually?

I am fairly familiar with invoking firebase firestore functions manually for testing. I have done this in the past with the docs here. In short I make a wrappedOnWrite variable, assign it to my admin sdk.wrap(my firebase function), and then I invoke it with an object that represents the firestore collection before and after the call. Example:
const testEnv = functions({ projectId: **** }, '****');
let wrappedOnWrite:
| WrappedScheduledFunction
| WrappedFunction<Change<QueryDocumentSnapshot>>;
beforeAll(() => {
// wrap the firebase function, ready to be invoked
wrappedOnWrite = testEnv.wrap(moderateCompetition);
});
const changeDoc: Change<QueryDocumentSnapshot> = {
before: testEnv.firestore.makeDocumentSnapshot(dataBefore, path),
after: testEnv.firestore.makeDocumentSnapshot(dataAfter, path),
};
// call firebase function with the changes inputted to the function
await wrappedOnWrite(changeDoc);
This is great for testing my firestore collections with jest, however, I am never seen this done with firebase storage, and I haven't been able to find many useful resources either. I have a pretty basic firestore .onFinalize function for storage:
export const blurImages = functions.storage.object().onFinalize(async (object) => {}
Is there any way to manually test it like in the example I gave above? When I initially deployed the function, it ran recursively and charged my company a couple of dollars, and I need to be able to run it periodically so that recession doesn't happen on the live function. Thanks in advance :)

How to update a document when a document is added to a specified collection in cloud firestore?

I have 2 collections in my firestore (global and local) and when I add a doc to local I need to update a field in the global doc by 1
Below is the code I have for the same. I am very new to this so I might have some syntactical error as well, please do highlight if you find any.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello world");
}); // For testing, even this is not being deployed
exports.updateGlobal = functions.firestore
.document("/local/{id}")
.onCreate((snapshot, context) => {
console.log(snapshot.data());
return admin
.firebase()
.doc("global/{id}")
.update({
total: admin.firestore.FieldValue.increment(1),
});
});
The Terminal says "function failed on loading user code"
Before this, it showed something along the lines of "admin is undefined" or "cannot access firestore of undefined" which I'm unable to replicate now.
This is a part of a react app which has normal firestore working through firebase npm module
Any other info needed regarding the issue I'll edit the question accordingly, thank you so much for the help.
In addition to loading the firebase-functions and firebase-admin modules, you need to initialize an admin app instance from which Cloud Firestore changes can be made, as follows:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
//...
I see another problem in your CF. You need to use the context object to get the value of id.
exports.updateGlobal = functions.firestore
.document("/local/{id}")
.onCreate((snapshot, context) => {
const docId = context.params.id;
return admin
.firebase()
.doc("global/" + docId)
.update({
total: admin.firestore.FieldValue.increment(1),
});
});
You can also use template literals as follows:
return admin
.firebase()
.doc(`global/${docId}`)
//...

Why is the firebase cloud function not triggering when document is created at responses

exports.createHook = functions.database.ref('/Responses/{ResponsesId}').onCreate((snap, context) => {
console.log('triggered')
var response = snap.val
console.log(response.text);
});
I've written to firestore and its not triggering, what am I missing?
Here is a picture of my functions panel its clearly deploying to the cloud
Here is a picture of the logs its only logging when the function is built so it isn't executing.
I have written to firestore and it is not triggering
You may have written to Firestore, but your code is written as a Firebase Realtime Database trigger (it uses functions.database). You need to use Firestore triggers to respond to events in Firestore (alternatively, you need to write your updates into a Realtime Database, not Firestore).
It is very easy to get these confused (they're named so similarly!) but they are not the same and need to be coded differently.
For example, the prototype for a Firestore onCreate trigger should look something like:
exports.createHook = functions.firestore
.document('Responses/{ResponsesId}')
.onCreate((change, context) => { .... }
Also in the comment thread I note that you said "onCreate should call every time there is a write to the reference". This is not correct. onCreate should only be called when the document is first written to.

Admin SDK cannot set settings for Firestore

So, I've been getting this warning recently:
The behavior for Date objects stored in Firestore is going to change
AND YOUR APP MAY BREAK.
To hide this warning and ensure your app does not break, you need to add the
following code to your app before calling any other Cloud Firestore methods:
const firestore = new Firestore();
const settings = {/* your settings... */ timestampsInSnapshots: true};
firestore.settings(settings);
With this change, timestamps stored in Cloud Firestore will be read
back as Firebase Timestamp objects instead of as system Date objects.
So you will also need to update code expecting a Date to instead
expect a Timestamp. For example:
// Old:
const date = snapshot.get('created_at');
// New:
const timestamp = snapshot.get('created_at');
const date = timestamp.toDate();
Please audit all existing usages of Date when you enable the new
behavior. In a future release, the behavior will change to the new
behavior, so if you do not follow these steps, YOUR APP MAY BREAK.
I am trying to implement the suggested correction in the admin SDK in my Cloud Functions code, since most of what I am doing is through there.
I tried using admin.firestore().settings({ timestampsInSnapshots: true }) but got the following warning:
admin.firestore(...).settings is not a function
How do I solve it?
I had the same problem. I had to update firebase-functions and firebase-admin.
To upgrade, go to your CLI, then
ProjectDirectory > Functions > npm install firebase-functions#latest firebase-admin#latest --save
Then, at the top, before triggering functions:
const firestore = admin.firestore();
const settings = {timestampsInSnapshots: true};
firestore.settings(settings);
To prevent the "Firestore.settings() has already been called" error, change
db.settings(settings);
to
try{ db.settings(settings); }catch(e){}
i solved with:
const settings = { timestampsInSnapshots: true };
const db = admin.firestore();
db.settings(settings);
db.collection('any');
Try configuring the settings right after initializing the admin SDK that might help.

How to read Firebase Database entry in Firebase Cloud Functions' index.js?

I am trying to create device to device push notifications for an iOS app using Firebase Cloud functions. I want to trigger an event whenever a new child is created in database at reference '/user-notifications/{notificationRecipientUid}/{challengeId}'. Here is my index.js code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendWinLoseOrTieNotification = functions.database.ref('/user-notifications/{notificationRecipientUid}/{challengeId}').onWrite(event => {
...
const challengeId = event.params.challengeId;
functions.database.ref('/challenges/' + challengeId).once('value').then(function(snapshot) {
const challengerUid = snapshot.val().challengerUid;
...
});
});
When a new child is added in the database at that location, I get this error, "TypeError: functions.database.ref(...).once is not a function", in Firebase Console's Functions Logs. So there is no 'once' method available
on ref like in web api:
firebase.database().ref('...').once('value').then(function(snapshot) {
...
});
My question is: How to read an existing database value inside index.js?
Well, the solution is to use admin instead of firebase like so:
admin.database().ref('...').once('value').then(function(snapshot) {
...
});

Categories

Resources