I'm changing real time database to Firestore.
Using cloud function trigger onUpdate() always failed with error message.
here's my cloud function index.js
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const serviceAccount = require("./service_account.json");
const friendProcess = require("./friend_process");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://projec-name.firebaseio.com"
});
exports.friendProcess = functions.firestore.document("users/{userId}/friends/{requestId}").onUpdate(friendProcess);
and this code is friend_process.js
const admin = require("firebase-admin");
module.exports = function(event) {
const userId = event.params.userId;
const updatedData = event.data.data();
const requestId = updatedData.fromUid;
const previousData = event.data.previous.data();
console.log("update data", updatedData);
console.log("requestId", requestId);
console.log("userId", userId);
if (previousData.status === "request" && updatedData.status === false) {
console.log("updatedData.action ", updatedData);
console.log("ref", event.data.ref);
return admin
.firestore()
.collection("users")
.doc(requestId)
.collection("friends")
.doc(userId)
.get()
.then(doc => {
return console.log("doc ", doc);
})
.catch(error => {
return console.log("error ", error);
});
}
return;
};
here's my console log
firebase console log link
Error: Unexpected error while acquiring application default credentials: Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information.
at GoogleAuth. (/user_code/node_modules/firebase-admin/node_modules/google-auth-library/build/src/auth/googleauth.js:229:31)
at step (/user_code/node_modules/firebase-admin/node_modules/google-auth-library/build/src/auth/googleauth.js:47:23)
at Object.next (/user_code/node_modules/firebase-admin/node_modules/google-auth-library/build/src/auth/googleauth.js:28:53)
at fulfilled (/user_code/node_modules/firebase-admin/node_modules/google-auth-library/build/src/auth/googleauth.js:19:58)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
my package.json
"firebase-admin": "^5.11.0",
"firebase-functions": "^0.9.1",
Related
I have a simple https firebase cloud function which get all user doc from firestore but it actually give me error of
Received RST_STREAM with code 2 triggered by internal client error: Protocol error
This is my index file is
I have initailized the app
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import {helloWorld} from "./apis/recJobs";
// eslint-disable-next-line #typescript-eslint/no-var-requires
const serviceAccount = require("../serviceAccount.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "*************",
});
// APIs
export const hello = functions.region(
"asia-south1"
).https.onRequest(helloWorld);
This is my HelloWorld Function which is straight forward to get all docs from firestore
import * as admin from "firebase-admin";
export const helloWorld = (req :any, res:any) => {
try {
// get all users doc
const db = admin.firestore();
// get all docs from user
const snapshot = db.collection("user").get();
snapshot.then((data) => {
console.log("data is :", data);
res.status(200).send({
ok: "Success",
});
}
).catch((error) => {
console.log("error is :", error);
res.status(400).send({
ok: error,
});
}
);
} catch (error) {
console.log("error is :", error);
res.status(400).send({
ok: "Final error",
});
}
};
It should return all the user docs
I have a cloud function in which I am listening to the onCreate event of a firestore collection. When the cloud function is triggered I am getting a reference error. Below are the cloud function code and the error.
const functions = require('firebase-functions')
const serviceAccount = require('./serviceAccountKey.json')
const admin = require('firebase-admin')
const { firestore } = require('firebase-admin')
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://my-app-id.firebaseio.com', // Here I have replaced my real id for privacy
})
const db = admin.firestore()
exports.handleDiscussionReplyAdded = functions.firestore
.document('/discussions/{discussionId}/replies/{replyId}')
.onCreate(async (snap, context) => {
try {
// 1. Creating a ref to parent chat doc
const discussionRef = db
.collection('discussions')
.doc(context.params.discussionId)
// 2. Updating the data
await discussionRef.update({
totalReplies: firestore.FieldValue.increment(1),
})
// Return true if everything went fine
return true
} catch (error) {
// Return error if something went wrong
functions.logger.error(`Error: ${JSON.stringify(error)}`)
return error
}
})
{
"severity": "ERROR",
"message": "ReferenceError: firestore is not defined\n at /Users/syedalirazabokhari/Desktop/Development/React/omanshopping/functions/index.js:23:23\n at cloudFunction (/Users/syedalirazabokhari/Desktop/Development/React/omanshopping/functions/node_modules/firebase-functions/lib/cloud-functions.js:134:23)\n at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:590:16\n at runFunction (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:577:15)\n at runBackground (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:589:11)\n at processBackground (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:572:11)\n at invokeTrigger (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:647:19)\n at handleMessage (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:734:15)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)"
}
I tried to debug the issue but unable to resolve. I have also updated the firebase-admin to the latest version 9.5.0 as of now.
Removing the unnecessary import const { firestore } = require('firebase-admin') and then changing firestore.FieldValue.increment(1) to admin.firestore.FieldValue.increment(1) fixed the error.
Issue: Type Error
I setup a Firestore Cloud Function to call from my Android app which is being called as expected, however I am unable to access a Firestore document from within the method and receiving a TypeError in the logs.
Attempted Solutions
functions.firestore().document('qa/content/feeds/main/content/'+contentTitle)
functions.firestore().ref('qa/content/feeds/main/content/'+contentTitle)
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
const MAIN_FEED_TYPE = "MAIN";
const SAVED_FEED_TYPE = "SAVED";
const ARCHIVED_FEED_TYPE = "ARCHIVED";
const SAVE_USER_ACTION = "SAVE";
const ARCHIVE_USER_ACTION = "ARCHIVE";
const SAVED_PATH = "saved"
const ARCHIVED_PATH = "archived"
exports.updateQualityScore = functions.https.onCall((data, context) => {
const environment = data.environment
const feedType = data.feedType
const action = data.action
const contentTitle = data.contentTitle
const uid = context.auth.uid;
var feedTypePath
if (feedType === SAVED_FEED_TYPE) {
feedTypePath = SAVED_PATH
} else if (feedType === ARCHIVED_FEED_TYPE) {
feedTypePath = ARCHIVED_PATH
}
admin.firestore().ref('qa/content/feeds/main/content/'+contentTitle)
.get().then(function(doc) {
console.log('Trigger fired on content: '
+ contentTitle + " | user: " + uid
+ " | action: " + action + ' | feedType: ' + feedType);
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
console.log("No such document!");
}
return {
status: 'Get content success.'
}
}).catch(function(error) {
console.log("Error getting document:", error);
return {
status: 'Get content error.'
}
});
});
Firestore doesn't have a ref() method. Realtime Database does. You're probably confusing the two.
With Firestore, you deal with collections and documents, and there are different methods to get a hold of collection and document references. Maybe you meant to use the doc() method instead, like this?
admin.firestore().doc('qa/content/feeds/main/content/'+contentTitle)
Sorry wrong answer.
You need to pass credential when initializing app.
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();
or
admin.initializeApp({
credential: admin.credential.cert({
projectId: '<PROJECT_ID>',
clientEmail: 'foo#<PROJECT_ID>.iam.gserviceaccount.com',
privateKey: '-----BEGIN PRIVATE KEY-----\n<KEY>\n-----END PRIVATE KEY-----\n'
}),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
initialize the sdk
Quick Start
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const firebase = require('firebase/app');
const credentials = require('./credentials.json');
const db = admin.firestore();
const user = require('./http-functions/user-creation')
var config = {
apiKey: "KEY",
authDomain: "ecommerce.firebaseapp.com",
databaseURL: "https://ecommerce.firebaseio.com",
projectId: "ecommerce",
storageBucket: "ecommerce.appspot.com",
messagingSenderId: "ID"
};
firebase.initializeApp(config)
admin.initializeApp({
credential: admin.credential.cert(credentials),
databaseURL: "https://ecommerce.firebaseio.com",
projectId: "ecommerce"
});
exports.addUser = functions.https.onRequest((req, res) => user.addUser(req, res, db, firebase))
I'm importing firebase so that I can use the firebase.auth() to create a new user on cloud functions firestore. But I'm having this error where it says that when I run my firebase deploy:
Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.
at FirebaseAppError.FirebaseError [as constructor]
Below is the code for adding a new user
module.exports = {
addUser: function(req, res, db, firebase, admin) {
firebase.auth().createUserWithEmailandPassword(email, password)
.then(userRecord => {
const uid = userRecord.uid;
const email = userRecord.email;
return firebase.firestore()
.collection('users')
.doc(uid)
.set({email: email},
{merge: true});
})
.catch(err => {
console.log(err)
})
}
}
Try assigning the intitializeApp into a const and use it instead of firebase.auth()
Something like:
var config = {
apiKey: "KEY",
authDomain: "ecommerce.firebaseapp.com",
...
};
const firebaseApp = firebase.initializeApp(config)
module.exports = {
addUser: function(req, res, db, firebase, admin) {
firebaseApp.auth().createUserWithEmailandPassword(email, password)
...
}
}
I am trying to make a notification function to deploy using cloud functions of firebase
I did the first part of the code and it was successfully done which is:
'use-strict'
const functions = require('firebase-functions');
//const paypal=require('paypal-rest-sdk');
const admin=require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification=functions.firestore
.document("Users/{user_id}/Notifications/{notification_id}")
onWrite((change, context)=>{
const user_id=context.params.user_id;
const notification_id=context.params.notification_id;
});
without returning promise and it was ok but when i tried to complete like this:
'use-strict'
const functions = require('firebase-functions');
//const paypal=require('paypal-rest-sdk');
const admin=require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification=functions.firestore
.document("Users/{user_id}/Notifications/{notification_id}")
.onWrite((change, context)=>{
const user_id=context.params.user_id;
const notification_id=context.params.notification_id;
return admin.firestore().collection("Users").doc(user_id)
.collection("Notifications")
.doc(notification_id)
.get()
.then(queryResult=>{
const from_user_id=queryResult.data().from;
const from_data=admin.firestore()
.collection("Users").doc(from_user_id).get();
const to_data=admin.firestore().collection("Users")
.doc(user_id).get();
return Promise.all([from_data,to_data]).then(result=>{
const from_name=result[0].data().name;
const to_name=result[1].data().name;
console.log("from :"+from_name+"TO"+to_name);
});
});
// console.log("user_id"+ user_id+ "notification_id"+notification_id);
});
I have these 2 errors in node.cm:
1-Avoid nesting promises
2-each then()should return a value
how can i fix this problem???
Send push notification through FCM and cloud function when a change in Firestore database
You can try like this
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.firestore
.document('/users/{documentId}')
.onWrite((change, context) => {
console.log("CHANGE in DOCUMENT ID : " + context.params.documentId);
// Fetch data using standard accessors
const userId = change.after.data().userId;
const ownerId = change.after.data().ownerId;
console.log('We have a new request UID:', userId, 'for owner:', ownerId);
const owner_data = admin.firestore().collection('users').doc(ownerId).get();
const user_data = admin.firestore().collection('users').doc(userId).get();
return Promise.all([owner_data, user_data]).then(result => {
const ownerFCMToken = result[0].data().fcmToken;
const userName = result[1].data().displayName;
console.log("OWNER Token : " + ownerFCMToken + " USER: " + userName);
const payload = {
notification: {
title: 'Test title!',
body: `${userName} sent you a following request.`
// icon: follower.photoURL
}
};
admin.messaging().sendToDevice(followedFCMToken, payload)
.then(function (response) {
console.log("Push response : " + response);
return response
})
.catch(function (error) {
console.error("Error in sending push");
});
});