My code :
exports.fcmSend = functions.firestore.document('messages/{userId}').onCreate(event => {
console.log("fcm send method");
const message = event.data.data();
const userId = event.params.userId;
const token_id = 'asdfsadfdsafds';
let token = "";
const payload = {
notification: {
title: "Test",
body: "Test",
icon: "https://placeimg.com/250/250/people"
}
};
db.collection('fcmTokens').doc('token_id').get().then((doc) => {
console.log(doc.id, '=>', doc.data());
const data = doc.data();
token = data.token;
console.log("token", token);
})
.then(() => {
return event.data.ref.set({"title": "hello"}).sendToDevice(token, payload);
})
.catch((err) => {
console.log('Error getting documents', err);
return err;
});
});
Error :
Error getting documents TypeError:
event.data.ref.set(...).sendToDevice is not a function
at db.collection.doc.get.then.then (/user_code/index.js:117:50)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
There are two separate Firebase products involved here:
Cloud Firestore, where you stroke the FCM tokens for a user.
the Cloud Messaging Admin SDK, which you use to send notifications to a user.
The sendToDevice method exists on the Admin SDK for Cloud Messaging, not on a Firestore database reference where you're trying to invoke it.
To fix the problem you'll first need to import the Admin SDK into your index.js:
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
Then you modify your functions for step 1 and 2. It should look something like this:
// Load the tokens from Firestore
db.collection('fcmTokens').doc('token_id').get().then((doc) => {
console.log(doc.id, '=>', doc.data());
const data = doc.data();
token = data.token;
console.log("token", token);
const payload = {
notification: {
title: 'hello',
}
};
return admin.messaging().sendToDevice(token, payload)
})
.catch((err) => {
console.log('Error getting documents', err);
return err;
});
Related
I’m trying to create a push notification and after a comment is made in my realtime database.
I use this code which I learned from here
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin';
export const sendenPushNeu = functions.database
.ref ('/placeID/{placeID}')
.onCreate((snapshot, context) => {
var app = admin.initializeApp({
credential: admin.credential.cert('/Users/...Desktop/firebasedesktop/key.json')
});
var registrationToken = 'dplk1...bS7eu';
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
})
But I don't get a notification.
I am new to javascript and cannot see what is wrong here.
I am trying to run the below cod which initialises the Firebase Admin SDK, and send a notification message.
const admin = require('firebase-admin/app');
const errorCodes = require('source/error-codes');
const PropertiesReader = require('properties-reader');
const prop = PropertiesReader('properties.properties');
exports.sendSingleNotification = async (event, context) => {
const params = event.queryStringParameters;
var serviceAccount = require("xxx-xxx-firebase-adminsdk-xxx-xxx.json");
try {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
console.log("INITIALIZED");
// This registration token comes from the client FCM SDKs.
const registrationToken = params.fcmtoken;
console.log()
const message = {
notification: {
title: 'FooCorp up 1.43% on the day',
body: 'FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
token: registrationToken
};
// Send a message to the device corresponding to the provided
// registration token.
admin.getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
return {"response":response}
})
.catch((error) => {
console.log('Error sending message:', error);
return {"error 1":error}
});
} catch (error) {
console.log(error);
return {"error 2":error}
}
};
Here the serviceAccount means the path of the Firebase private key file which is in the root of this project.
However when I run this code I always end up with the following error.
START RequestId: e66ffdd9-ab9c-4a68-ade2-7cfa97f42c31 Version: $LATEST
at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)] (/var/task/source/fcm/send-single-notification.js:14:42)rt' of undefined
END RequestId: e66ffdd9-ab9c-4a68-ade2-7cfa97f42c31
Something is undefined and I can't figure out what it is or what the error is.
How can I fix this?
I'm sending push messages using FCM through Firebase Functions. The messages are being sent properly, but I'm getting the 408 time-out error after the message is sent. I'm suspecting it might have to do with the unregistered tokens not being cleaned up because:
if I were to send another message to the same device, the same timeout occurs and
the only error message I get from the Firebase log is Function execution took 60002 ms, finished with status: 'timeout'.
exports.sendMessage = functions.https.onRequest(async (request, response) => {
const {
sender,
recipient,
content,
docID
} = request.body
functions.logger.log(
"docID:",
docID,
);
// Get the list of device notification tokens.
let deviceTokens; let ref;
try {
ref = admin.firestore().collection("deviceToken").doc(recipient);
const doc = await ref.get();
if (!doc.exists) {
console.log("No such document!");
response.status(500).send(e)
} else {
console.log("doc.data():", doc.data());
deviceTokens = doc.data().token;
}
} catch (e) {
response.status(500).send(e)
}
let senderProfile;
try {
senderProfile = await admin.auth().getUser(sender);
console.log("senderProfile", senderProfile);
} catch (e) {
console.log(e);
response.status(500).send(e)
}
// Notification details.
let payload = {
notification: {
title: senderProfile.displayName,
body: content,
sound: "default",
},
data: {
uid: senderProfile.uid,
displayName: senderProfile.displayName,
docID,
messageType: "status"
}
};
functions.logger.log(
"deviceTokens", deviceTokens,
"payload", payload,
);
// Send notifications to all tokens.
const messageResponse = await admin.messaging().sendToDevice(deviceTokens, payload);
// For each message check if there was an error.
messageResponse.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
"Failure sending notification to",
deviceTokens[index],
error,
);
// Cleanup the tokens who are not registered anymore.
if (error.code === "messaging/invalid-registration-token" ||
error.code === "messaging/registration-token-not-registered") {
const updatedTokens = deviceTokens.filter((token) => token !== deviceTokens[index]);
console.log("updatedTokens", updatedTokens);
ref.update({
token: updatedTokens,
})
.catch(function(e) {
console.error("Error removing tokens", e);
response.status(500).send(e)
});
}
}
});
response.status(200)
});
I'm unsure why the following isn't cleaning up the unregistered tokens:
const updatedTokens = deviceTokens.filter((token) => token !== deviceTokens[index]);
ref.update({
token: updatedTokens,
})
You always have to end HTTP functions with response.status(200).send() or response.status(200).end(). In the above function, you have response.status(200) so you have to end it either with response.status(200).send() or response.status(200).end(). Please check the documentation if it helps.
Hi this is my first time working with Firebase push notifications and I'm trying to send a test push notification to a specific device and I'm getting an error when checking the functions. Here is my code and the errors, any help is greatly appreciated.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.testPushNotifications = functions.https.onRequest((req, res) => {
res.send("Trying to send a message")
console.log("LOGGER --- trying to send a push notification..");
const uid = 'O5cN65bAe3Mf7uMr7DCF8GlvsHA3'
const fcmToken = 'cUQ-IcReLTQ:APA91bGgDRIQfFi7k4AIo45b4sXr.........'
return admin.database().ref('/users/' + uid).once('value', snapshot => {
const user = snapshot.val();
console.log("Username is " + user.userName);
const payload = {
notification: {
title: 'Push Notification',
body: 'Test Notification message'
}
}
admin.messaging().sendToDevice(fcmToken, payload)
.then(function(response) => { // 27:30 error Parsing error: Unexpected token =>
console.log('Successfully sent message:', response);
})
.catch(function(error) => {
console.log('Error sending message:', error);
});
});
})
If I remove the => I get the following warnings and error:
admin.messaging().sendToDevice(fcmToken, payload)
.then(function(response) {
console.log('Successfully sent message:', response);
})
.catch(function(error) {
console.log('Error sending message:', error);
});
27:11 warning Unexpected function expression prefer-arrow-callback
27:11 error Each then() should return a value or throw promise/always-return
30:12 warning Unexpected function expression prefer-arrow-callback
I'm making a react-redux app with firetore as database. Now, I wanted to use firebase cloud functions for handling stripe payments.
Here is the cloud function "createSubscription":
exports.createSubscription = functions.database
.ref("/teachers/{userId}/pro-membership/token")
.onWrite((event, context) => {
const tokenId = event.after.val();
const userId = context.params.userId;
if (!tokenId) throw new Error("Token Missing");
return admin
.database()
.ref(`teachers/${userId}`)
.once("value")
.then(snapshot => snapshot.val())
.then(user => {
console.log(user);
return stripe.subscriptions.create({
customer: user.customerId,
source: tokenId, **// Here is the error occuring**
items: [
{
plan: "pro-membership"
}
]
});
})
.then(sub => {
admin
.database()
.ref(`teachers/${userId}/pro-membership`)
.update({
status: "active"
});
})
.catch(err => {
console.log("ERRor", err);
});
});
Below is the error information from cloud function's logs:
source is not a valid parameter on a stripe.subscriptions.create request, see https://stripe.com/docs/api/subscriptions/create
Try updating the customer first, adding the token, https://stripe.com/docs/api/customers/update, then create a subscription!