A cloud firestore trigger has to happen whenever a new collection is to added to the cloud firestore. The cloud functions are successfully executed, but they are not triggering when a new doc was added to the firestore it means the logs are empty and no.of execute times is 0.The following the cloud function code.
const functions = require('firebase-functions');
const Firestore = require('#google-cloud/firestore');
const firestore = new Firestore();
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.wallet=functions.firestore
.document('Samyata/{authid}')
.onCreate(event => {
const db = admin.firestore();
const ID = event.params.authId
var pymntDetails = db.collection('Samyata').doc(ID).collection('Accounts').doc(ID);
var details = pymntDetails.set({
'stripecustomerId':'0',
//var bankAccount = db.collection('Samyata').doc(ID).collection('Accounts').doc(ID).doc('BankDetails');
//var bnkdetails = bankAccount.set({
//'AccountNumber':'',
//'RoutingNumber':''
//});//SET CLOSE for bank details
'deyaCoins':'0',
'BitCoins':'0',
'Ether':'0'
});//matched set paranthesis
return event.data.ref.update({
ID
});
});//end of onCreate event
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
Related
I want to retrieve the field value from a document snapshot which is the URL of a file in firebase storage and delete the file from firebase storage also the firestore document if the time of creation of the doc is before 24 hrs.
I am able to delete expired firestore documents successfully with the code below:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { firestore } = require("firebase-admin");
admin.initializeApp();
exports.removeExpiredDocuments = functions.pubsub.schedule("every 1 hours").onRun(async (context) => {
const db = admin.firestore();
const now = firestore.Timestamp.now();
const ts = firestore.Timestamp.fromMillis(now.toMillis() - 86400000); // 24 hours in milliseconds = 86400000
const snapshots = await db.collection("photos").where("timestamp", "<", ts).get();
let promises = [];
snapshots.forEach((snap) => {
promises.push(snap.ref.delete());
});
return Promise.all(promises);
});
but I don't know how to retrieve the field value(URL of file) from the document snapshot within the forEach block and delete the file from firebase storage.
Here's the firestore database:
The field value of photourl is to be retreived.
Thanks in advance!
I think code look like :
//some code ....
snap.docs.map((doc) => {
if (doc.exist) {
var url = doc.data().photourl;
//do something logic call to firestorage and deleted data base on url get
//write logic deleted url firebase after deleted success firestorage
}
});
I just typed a code in my index.js file of functions (firebase CLI).According to my code there must be a timeline collection created in cloud database of firebase.Function is healthy and there are no errors it gets deployed and even in the logs everything works fine. But still timeline collection is not created in the cloud databaese when I follow a user in my app.
this is my code:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.onCreateFollower = functions.firestore
.document("/followers/{userId}/userFollowers/{followerId}")
.onCreate(async (snapshot, context) => {
console.log("Follower Created", snapshot.id);
const userId = context.params.userId;
const followerId = context.params.followerId;
// 1) Create followed users posts ref
const followedUserPostsRef = admin
.firestore()
.collection("posts")
.doc(userId)
.collection("userPosts");
// 2) Create following user's timeline ref
const timelinePostsRef = admin
.firestore()
.collection("timeline")
.doc(followerId)
.collection("timelinePosts");
// 3) Get followed users posts
const querySnapshot = await followedUserPostsRef.get();
// 4) Add each user post to following user's timeline
querySnapshot.forEach(doc => {
if (doc.exists) {
const postId = doc.id;
const postData = doc.data();
return timelinePostsRef.doc(postId).set(postData);
}
});
});
Since you want to execute a variable number of asynchronous calls in parallel, you should use Promise.all(), in order to wait that all these different asynchronous calls are completed before indicating to the CF platform that it can cleanup the CF. See https://firebase.google.com/docs/functions/terminate-functions for more details.
exports.onCreateFollower = functions.firestore
.document("/followers/{userId}/userFollowers/{followerId}")
.onCreate(async (snapshot, context) => {
const userId = context.params.userId;
const followerId = context.params.followerId;
// ...
// 3) Get followed users posts
const querySnapshot = await followedUserPostsRef.get();
// 4) Add each user post to following user's timeline
const promises = [];
querySnapshot.forEach(doc => {
//query results contain only existing documents, the exists property will always be true and data() will never return 'undefined'.
const postId = doc.id;
const postData = doc.data();
promises.push(timelinePostsRef.doc(postId).set(postData));
});
return Promise.all(promises);
});
I've been trying to deploy a Cloud Function to my Firebase project.
It's my first time doing so, also my first time programming with JavaScript.
Here's my code in Node.JS:
'use strict'
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
const firebaseTriggers = functions.region('europe-west1').firestore;
const db = admin.firestore();
exports.postNotification = firebaseTriggers
.document('/post notifications/{notificatioId}').onWrite((snap, context) => {
const notifcationRecieverId = snap.data().mReciever;
const payload = {
data: {
notification_type: 'POST',
title: snap.data().mTitle,
body: snap.data().mDescription,
sender_id: snap.data().mSender,
reciever_id: snap.data().mReciever,
notification_id: context.params.notificatioId
}
};
return db.collection('dog owners')
.document(notifcationRecieverId)
.get()
.then(recieverDoc => {
console.log('Retrieving FCM tokens');
const tokens = recieverDoc.data().mTokens;
console.log('Sending notification payload');
return admin.message().sendToDevice(tokens, payload);
});
});
Upong deployment, I'm getting the following error:
Can someone help me understand why?
Firstly you have got space in your colleciton name. This is bad convetion.
post notifications => postNotifications
I have a simple get request built using node, express to retrieve data from datastore. I am not able to get back the results. 'get' request async call is stuck. Not sure what is happening.
const express = require('express');
const {Datastore} = require('#google-cloud/datastore');
const app = express();
// Your Google Cloud Platform project ID
const projectId = 'xxx';
// Creates a client
const datastore = new Datastore({
projectId: projectId,
keyFilename: '/Masters-LUC/spring-2019/internship/service-keys/xxx.json'
});
const query = datastore
.createQuery('approvals')
.filter('status', '=', 'yes');
app.get("/api/get", (req, res, next) => {
query.run().then(([documents]) => {
documents.forEach(doc => console.log(doc));
});
});
module.exports = app;
I re-wrote the same using async function. The below is working. Why not the above?
// Retrieve data from datastore
async function quickStart() {
// Your Google Cloud Platform project ID
const projectId = 'xxx';
// Creates a client
const datastore = new Datastore({
projectId: projectId,
keyFilename: '/Masters-LUC/spring-2019/internship/service-
keys/xxx.json'
});
const query = datastore
.createQuery('approvals')
.filter('status', '=', 'yes');
const [approvals] = await datastore.runQuery(query);
console.log('Tasks:');
approvals.forEach(task => console.log(task));
}
quickStart().catch(console.error);
The two things I notice that is different between your two functions. In the first you reuse the query object across function invocations. Query objects should not be reused.
The second thing I notice is that you don't use res that's passed into your function parameter to app.get().
Modified working code -
app.get("/api/approvals/", (req, res, next) => {
const query = datastore
.createQuery('approvals');
query.run().then((approvals) => {
approvals.forEach(appr => console.log(appr)); // This is used to log results on console for verification
// loading results on the response object to be used later by client
res.status(200).json(
{
message: "Request was processed successfully!",
approvals : approvals
}
);
})
})
I want to add new collection to a doc that already exists in firestore.Is it possible? The following is the code for doing that, I used cloud fucntions for doing that.Whenever a document is created in firestore then the following cloud function has to trigger
const functions = require('firebase-functions');
const Firestore = require('#google-cloud/firestore');
const firestore = new Firestore();
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.myWallet = functions.firestore
.document('Samyata/{authid}')
.onCreate(event =>{
const ID = event.params.authid
const db = admin.firestore();
var data = {
Bitcoins : '0',
Ether : '0',
deyaCoins : '0'
};
var docRef = db.collection('Samyata').doc(ID);
var updateDoc = docRef.update({
db.collection('Samyata').doc(ID).collection('Wallet').doc(ID).set(data);});
//var updateRef = docRef.update();
});//end of onCreate()
Try this :)
return db.collection('Samyata').doc(ID).collection('Wallet').doc(ID).set(data);
or you can concatenate the path like this
return db.collection(`Samyata/${ID}/Wallet/${ID}`).add(data)
transactionData= {
TimeStamp: "123",
SomeBooleanValue: false
}
var addDocToNewCollResult= admin.firestore().collection('CollectionLevel1').doc(userID).collection('CollectionLevel2').doc(transactionID).collection('CollectionLevel3').doc("OtherID").set( transactionData );