FCM Parsing error: Identifier 'functions' has already been declared - javascript

I'm learning FCM and I'm currently editing the index.js file to execute Firebase functions. However, when I deploy the function 'sendPushNotifications' I receive the error "Parsing error: Identifier 'functions' has already been declared." I've only declared it once within the file so I'm not sure if it's something beyond the file that I have to edit. I apologize for the poor formatting of the code below, I'm still not too used to pasting code into SO.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendPushNotifications = functions.https.onRequest((req,res) => {
response.send("Attempting to send push notification...")
console.log("LOGGER --- Trying to send push mesage")
var registrationToken = 'dSXeXBSHShU:APA91bFHWw_jNF1pr8Toq3OelqtyXrTZZssJW7YHMlP-tiNJ41uuO-pS--rfWduPFEEC72FchtDRHbt1RMM1e5kSWHUDVhWFvIAtx82LjIDiUNlmk14Ix_SLtrN_vB55rbr1tgcpS3CW';
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
admin.messaging().send(message)
.then((response) => {
console.log('Successfully sent message:', response);
return response
})
.catch((error) => {
console.log('Error sending message:', error);
throw new Error("Error sending message");
});
})

got the same error.
Check your code, you might have declared the "const function" multiple time ;)

Related

Interacting with firebase firestore from firebase cloud functions

I am trying to interact with firebase firestore from my cloud function. The cloud functions looks like the following:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
admin.initializeApp();
const db = admin.firestore();
exports.addVote = functions.https.onCall((data, context) => {
return db
.doc("sdd-enheter/enhet/votes/voteID")
.set({ user: "user", vote: 0 });
});
When calling the function from the client side I get a firebase internal error, indicating that the function has been called but throws an error. What should I do to fix this?
Your function needs to return a promise or otherwise terminate by throwing an https error. Throwing the https error will give the client back a relevant error that it can handle, so consider making that a habit. The function below covers both of those bases. If you still get an error then share that error with us as it appears in the console's function log.
exports.addVote = functions.https.onCall((_data, _context) => {
const db = admin.firestore();
try {
return db.doc("sdd-enheter/enhet/votes/voteID").set({user: "user", vote: 0});
} catch (error) {
throw new functions.https.HttpsError("unknown", "Failed to add vote.", error);
}
});

getting error while deploying firebase cloud pub-sub code

while deploying pub-sub code on firebase i'm getting following error :
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function failed on loading user code. This is likely due to a bug in the user code. Error message: Code in file index.js can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: /srv/node_modules/#google-cloud/pubsub/build/src/pubsub.js:527
async *listSchemas(view = schema_1.SchemaViews.Basic, options) {
^
I'm not getting why this error is occurring.
following is the code:
exports.publish = async (req, res) => {
if (!req.body.topic || !req.body.message) {
res.status(400).send('Missing parameter(s); include "topic" and "message" properties in your request.');
return;
}
console.log(`Publishing message to topic ${req.body.topic}`);
const topic = pubsub.topic(req.body.topic);
const messageObject = {
data: {
message: req.body.message,
},
};
const messageBuffer = Buffer.from(JSON.stringify(messageObject), "utf8");
try {
await topic.publish(messageBuffer);
res.status(200).send("Message published.");
} catch (err) {
console.error(err);
res.status(500).send(err);
return Promise.reject(err);
}
};
I'm going to guess that this function is set to use the Node 8 runtime, since support for async iterators was added in Node 10. The Pub/Sub library has only supported Node 10 and above since 2.0, so bumping the runtime version on the Firebase function should help:
https://firebase.google.com/docs/functions/manage-functions#set_nodejs_version
Unfortunately I don't have enough points to ask for more details on the original question, but hopefully that helps!

Any data passed to a Firebase Function returns Undefined

I've made a firebase function which every time I pass data to it and try to use the data, it returns that the data is undefined. This is the function I made:
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
// CORS Express middleware to enable CORS Requests.
const cors = require('cors')({origin: true});
admin.initializeApp();
exports.addUser = functions.https.onRequest((req, res) => {
const handleError = (error) => {
console.log('Error creating new user:', error);
//sends back that we've been unable to add the user with error
return res.status(500).json({
error: err,
});
}
try {
return cors(req, res, async () => {
console.log(req);
const uid = req.uid;
const dob = req.dob;
const postcode = req.postcode;
const sex = req.sex;
const username = req.username;
admin.firestore().collection('users').doc(uid).set({
dob:dob,
postcode:postcode,
sex:sex,
username:username,
})
.then(function(userRecord) {
console.log('Successfully created new user:', userRecord.username);
// Send back a message that we've succesfully added a user
return res.status(201).json({
message: 'User stored',
id: req.body.uid,
});
})
.catch(function(error) {
return handleError(error);
});
});
} catch (error) {
return handleError(error);
}
});
This is how I call it within react:
const addUserFunc = firebase.functions().httpsCallable('addUser');
console.log("Calling user func " + user.uid)
addUserFunc({
uid:user.uid,
dob:dob,
postcode:postcode,
sex:sex,
username:username,
}).then(function(result) {
console.log(result);
}).catch(err => {
console.log(err)
setErrors(prev => ([...prev, err.message]))
});
I've printed the data before sending the request and it definitely exists. I've also tried getting it within the function using req.body and req.query but this just returns the same.
This is the error I get in the firebase function logs:
Error: Value for argument "document path" is not a valid resource path. The path must be a non-empty string.
at Object.validateResourcePath (/srv/node_modules/#google-cloud/firestore/build/src/path.js:406:15)
at CollectionReference.doc (/srv/node_modules/#google-cloud/firestore/build/src/reference.js:1982:20)
at cors (/srv/index.js:44:51)
at cors (/srv/node_modules/cors/lib/index.js:188:7)
at /srv/node_modules/cors/lib/index.js:224:17
at originCallback (/srv/node_modules/cors/lib/index.js:214:15)
at /srv/node_modules/cors/lib/index.js:219:13
at optionsCallback (/srv/node_modules/cors/lib/index.js:199:9)
at corsMiddleware (/srv/node_modules/cors/lib/index.js:204:7)
at exports.addUser.functions.https.onRequest (/srv/index.js:31:16)
This is the error return in the web console for the react app:
Access to fetch at 'https://***/addUser' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I tested the function within using the emulator and passing the values using the link which works there but just not when deployed.
Any help would be great.
Your Cloud Function is defined as a HTTPS Function, which means that you can access it over a URL, but then you're calling it from your code as a Callable Function. The two types are different and not interchangeable.
If you want to use the firebase.functions().httpsCallable('addUser'); in your client code, you'll have to modify your Cloud Function to be a Callable Function too. This mostly means that you get the parameters from data instead of res, and return responses instead of sending them through res.
exports.addUser = functions.https.onCall((data, context) => {
...
const uid = context.auth.uid; // automatically passed to Callable Functions
return admin.firestore().collection('users').doc(uid).set({
dob: data.dob,
postcode: data.postcode,
sex: data.sex,
username: data.username,
})
.then(function(userRecord) {
return {
message: 'User stored',
id: req.body.uid,
};
}).catch(err => {
throw new functions.https.HttpsError('dabase-error', error);
})
});
Alternatively, you can leave your Cloud Function as is and instead modify the calling code to use something like fetch().

Notification not being sent via firebase functions. "undefined" logged in console

I am trying to send a sample notification to all devices according to their token, however the token is being logged as "undefined" and the notification subsequently fails to deliver
The following lines from my code successfully show me the data from the database:
const notificationSnapshot = change.after.val(); //get new value
console.info(notificationSnapshot);
However, the following gives "undefined", despite the above retrieving the data successfully.
const userToken = notificationSnapshot.token;
console.info(userToken);
Is this not the correct way to retrieve the token to send the notification to all the registered devices in my firebase database?
my whole function (index.js)
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendSampleNotification = functions.database.ref('/User')
.onWrite((change, context) => {
const notificationSnapshot = change.after.val(); //get new value
const userToken = notificationSnapshot.token;
const name = notificationSnapshot.name;
const surname = notificationSnapshot.surname;
console.info(notificationSnapshot);
console.info(userToken);
var message = {
notification: {
title: 'test title',
body: 'test message'
},
token: userToken
};
admin.messaging().send(message).then((response) => {
console.log("Message sent successfully:", response);
return response;
})
.catch((error) => {
console.log("Error sending message: ", error);
});
});
I would say that your issue is very similar to this one since you are having a missing token (showed as undefined) due to the executions times, more or less what Doug was pointing out.
Note that the solution relies on considering the execution times and I’ve seen also that the implementation differs in some method executions but I would say the generals point in the same direction.

Javascript eslint error for require, export and console field

I have made a script for sending push notifications to my Firebase server, but javascript eslint is throwing error for const first.
Then I found on Google that I have to put ecmaVersion = 6 in my .eslintsrc file.
I did that then it is showing error on require, exports and console field.
I am using Atom as my compiler for code. This is my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.printUrl = functions.database.ref('images/{uid}').onWrite(event => {
var request = event.data.val();
var payload = {
data:{
url : request.url,
location : request.location
}
};
admin.messaging().sendToTopic(request.topic, payload)
.then(function(response){
console.log("Successfully sent message : ", response);
})
.catch(function(error){
console.log("Error sending message : ", error);
})
});
You need to let eslint know that you're working in a Node environment to get rid of the require and exports errors. So by adding this to your eslintConfig:
"env": {
"node": true
}
In order to allow the console.log, you will have to turn on the rule by adding this to your eslintconfig:
"rules": {
"no-console": 0
}
You can find more information here: https://eslint.org/docs/user-guide/configuring

Categories