can't get params from firebase function - javascript

I'm currently trying to send a confirmation email with sendgrid API from a firebase function.
The API is not the problem though, it seems to work fine, my problem is that I can't get the child oncreate's value (Firebase function log):
TypeError: Cannot read property 'participant_id' of undefined
at exports.SendEmail.functions.database.ref.onCreate.event (/user_code/index.js:15:38)
at Object.<anonymous> (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:112:27)
at next (native)
at /user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:82:36)
at /var/tmp/worker/worker.js:716:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
And here's my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const SENDGRID_API_KEY = functions.config().sendgrid.key;
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(SENDGRID_API_KEY);
exports.SendEmail = functions.database.ref('participants/{participant_id}').onCreate(event => {
const participant_id = event.params.participant_id;
const db = admin.database();
return db.ref(`participants/${participant_id}`).once('value').then(function(data){
const user = data.val();
const email = {
to: user.email,
from: 'recrutement.cisssme16#ssss.gouv.qc.ca',
subject: "Bienvenue au Blitz d'embauche 2018!",
templateId: 'dd3c9553-5e92-4054-8919-c47f15d3ecf6',
substitutionWrappers: ['<%', '%>'],
substitutions: {
name: user.name,
num: user.num
}
};
return sgMail.send(email)
})
.then(() => console.log('email sent to', user.email))
.catch(err => console.log(err))
});
This is not my first firebase function. I even copied pasted previous working codes which worked fined and I still get an undefined value!
What's the problem here? Did firebase changed event.params?
Also my participant_id is an integer value (ex.: 3827), if that changes something.
Thanks in advance!

The signature of the function is wrong, take a look at this example on Handle event data:
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onCreate((snapshot, context) => {
console.log('Uppercasing', context.params.pushId, original);
});
So just adjust your onCreate function and you'll be all set :)

Related

Algolia search error when "index.addObject()"

I've installed algolia using this tutorial: https://www.youtube.com/watch?v=dTXzxSlhTDM
I have firestore paid version and all was going okay till i created an item in my collection to try if it was working, but when i did it any item was added in my algolia index, so i went to cloud functions log and saw this:
addToIndex
TypeError: index.addObject is not a function
at exports.addToIndex.functions.firestore.document.onCreate.snapshot (/srv/index.js:15:22)
at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23)
at /worker/worker.js:825:24
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
I wasted 30 mins looking at the code, and rewriting it all perfectly exact as in the video, and searched for this error and didn't find anything, so here i'm
index.js
const functions = require('firebase-functions');
const algoliasearch = require('algoliasearch');
const APP_ID = functions.config().algolia.app;
const ADMIN_KEY = functions.config().algolia.key;
const client = algoliasearch(APP_ID, ADMIN_KEY);
const index = client.initIndex('items');
exports.addToIndex = functions.firestore.document('items/{itemId}')
.onCreate(snapshot => {
const data = snapshot.data();
const objectID = snapshot.id;
return index.addObject({ ...data, objectID });
});
exports.updateIndex = functions.firestore.document('items/{itemId}')
.onUpdate((change) => {
const newData = change.after.data();
const objectID = change.after.id;
return index.saveObject({ ...newData, objectID });
});
exports.deleteFromIndex = functions.firestore.document('items/{itemId}')
.onDelete(snapshot => index.deleteObject(snapshot.id));
The addObject method doesn't exist on the latest version. You have to use saveObject:
index.saveObject({ ...data, objectID })
Note that a tutorial for Algolia is available in Firebase documentation.

How to debug an ApolloServer's context function?

I'm trying to follow the GraphQL tutorial (https://www.apollographql.com/docs/tutorial/resolvers/), but I'm getting an error in the playground when I try to book a trip, with a stack trace starting like this:
"TypeError: Cannot read property 'id' of null",
" at UserAPI.bookTrips (/Users/kurtpeek/Documents/Scratch/fullstack-tutorial/start/server/src/datasources/user.js:35:38)",
In src/index.js, the ApolloServer (https://www.apollographql.com/docs/apollo-server/api/apollo-server/) is defined with an asynchronous context() function like so:
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const { createStore } = require('./utils');
const resolvers = require('./resolvers');
const LaunchAPI = require('./datasources/launch');
const UserAPI = require('./datasources/user');
const isEmail = require('isemail');
const store = createStore();
const server = new ApolloServer({
context: async ({ req }) => {
debugger;
const auth = (req.headers && req.headers.authorization) || '';
const email = Buffer.from(auth, 'base64').toString('ascii');
if (!isEmail.validate(email)) return { user: null };
const users = await store.users.findOrCreate({ where: { email }});
const user = users && users[0] ? users[0] : null;
return { user: { ...user.dataValues }};
},
typeDefs,
resolvers,
dataSources: () => ({
launchAPI: new LaunchAPI(),
userAPI: new UserAPI({ store })
})
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Since the error I'm seeing is the result of the context's user being null, I would like to step through the context() method to inspect the headers and see whether it contains a valid (encoded) email; as you can see I've set a debugger breakpoint at the start of that function.
However, when I run node inspect src/index.js, I immediately enter the debugger for an IntrospectionQuery:
If I press the 'Resume script execution' button, I just get back immediately to the same breakpoint.
Does this have something to do with the fact that context() is an async function? How can I step through the context() method with the debugger?
In the end, I just debugged it using console.log() commands. I had accidentally put the authorization in the 'Query Variables' section rather than the 'HTTP Headers' one. Moving it to 'HTTP Headers' produces the desired result:

ReferenceError: event is not defined firebase function

I am currently developing appointment application and notification is one of the application. As a result, I have been using firebase function for notifying a user if there is new appointment booked or cancel. I am getting an error that ReferenceError: event is not defined
Node.js code
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/Notifications/{PostKey}/{notification_id}').onWrite((data, context) => {
const user_id = context.params.PostKey;
const notification_id = context.params.notification_id;
console.log('We have a notification from : ', user_id,'this also notification_id',notification_id);
if(!event.data.val())
{
return console.log('A Notification has been deleted from the database : ', notification_id);
}
const deviceToken = admin.database().ref(`/User_Data/${user_id}/Device_Token`).once('value');
console.log('A Notification has been deleted from the database : ', deviceToken);
return deviceToken.then(result => {
const token_id = result.val();
const payload =
{
notification:
{
title:"Appointment has been booked",
body: "one of your Appointmtnt has been booked",
icon:"default"
}
};
return admin.messaging().sendToDevice(token_id,payload).then(response =>
{
return console.log('This was the notification Feature');
});
});
});
Error log
ReferenceError: event is not defined
at exports.sendNotification.functions.database.ref.onWrite (/user_code/index.js:16:9)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
at /var/tmp/worker/worker.js:733:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
**Database structure **
The error message is very precise. It's telling you that you used a variable called event on line 16, but you never defined it:
if(!event.data.val())

How to solve this Firebase cloud function Error: Cannot read property

I am following a tutorial where I am adding some Firebase Cloud Functions to my project (step 5). I have successfully deployed my cloud function to firebase but nothing happens when I add a new product manually in the Firebase Database console. I discovered that the Firebase cloud function is triggered but it is getting an error: "TypeError: Cannot read property 'productId' of undefined"
What am I doing wrong?
const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
exports.sendMessage = functions.firestore
.document('products/{productId}')
.onCreate(event => {
const docId = event.params.productId; // <-- error here
const name = event.data.data().name;
const productRef = admin.firestore().collection('products').doc(docId)
return productRef.update({ message: `Nice ${name}! - Love Cloud Functions`})
});
That tutorial must be out of date. Some things have changed in the Functions SDK when it released version 1.0. You can read about those changes here.
Database triggers are now passed two parameters instead of one. The new context parameter contains the value of wildcards in the reference path:
exports.sendMessage = functions.firestore
.document('products/{productId}')
.onCreate((snapshot, context) => {
const docId = context.params.productId;
If you want to continue with that tutorial, you'll have to manually convert all of its old stuff to new stuff.
OK. So thanks to Dough Stevensson's answer notifying me that the syntax was old I have now a solution:
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
var db = admin.firestore();
exports.sendMessage = functions.firestore
.document('products/{productId}')
.onCreate((snapshot, context) => {
const docId = context.params.productId;
const productRef = db.collection('products').doc(docId)
return productRef.update({ message: `Nice ${name}!`})
});

Can't be get any notification when the friend request one user to another user through nodejs in android Firebase Function

I'm trying to create notification simple AI for my chat application when i request form one user id to another user id it doesn't display any notification to other user id and in function there was shown the error as:
Error: Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array.
at FirebaseMessagingError.Error (native)
at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:241:16)
at Messaging.validateRegistrationTokensType (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:589:19)
at Messaging.sendToDevice (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:210:14)
at Promise.all.then.result (/user_code/index.js:92:32)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I'm not a good coder of nodejs i referred from some tutorial from google but it doesn't work for me can any one help me why this error will be shown and how to fixed it. also i have no any notification form one to another user id.
Here is my nodejs code:
index.js:
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/notifications/{user_id}/{notification_id}').onWrite(event => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
console.log('We have a notification from : ', user_id);
if(!event.data.val()){
return console.log('A Notification has been deleted from the database : ', notification_id);
}
const fromUser = admin.database().ref(`/notifications/${user_id}/${notification_id}`).once('value');
return fromUser.then(fromUserResult => {
const from_user_id = fromUserResult.val().from;
console.log('You have new notification from : ', from_user_id);
const userQuery = admin.database().ref(`Users/${from_user_id}/name`).once('value');
const deviceToken = admin.database().ref(`/Users/${user_id}/device_token`).once('value');
return Promise.all([userQuery, deviceToken]).then(result => {
const userName = result[0].val();
const token_id = result[1].val();
const payload = {
notification: {
title : "New Friend Request",
body: `${userName} has sent you request`,
icon: "default",
click_action : "com.rotaractnepalapp.rotraconversation_TARGET_NOTIFICATION"
},
data : {
from_user_id : from_user_id
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
return console.log('This was the notification Feature');
});
});
});
});
This is because:
const userName = result[0].val();
const token_id = result[1].val();
one of the above is empty, you need to add console.log() to check which one. Also you need to check your database and path database in ref() to be sure that there is a token.

Categories