I have an android app and want people (authenticated users) to send push notification each other from a message box. I'm using node.js with firebase cloud functions and I got this error on logs:
TypeError: Cannot read property 'userId' of undefined
at exports.sendNotification.functions.database.ref.onWrite.event (/user_code/index.js:10:33)
...
The message is successfully written to real-time database but the notification is not delivered to the receiver(user).
I read so many docs and same/similar problems so I'm aware that there are so many topics related to this but I couldn't solve the problem. I use index.js as the source code but changed some parts like onWrite section according to the documents I read.
The error indicates this line in the following code:
const receiverId = context.params.userId;
Something about params go wrong. Here is the small part of the code(with my changings):
let functions = require('firebase-functions');
let admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.database.ref('/messages/{userId}/{messageId}').onWrite((change,context) => {
//get the userId of the person receiving the notification because we need to get their token
const receiverId = context.params.userId;
console.log("receiverId: ", receiverId);
//get the user id of the person who sent the message
const senderId = change.child('user_id').val();
console.log("senderId: ", senderId);
//get the message
const message = change.child('message').val();
console.log("message: ", message);
//get the message id. We'll be sending this in the payload
const messageId = context.params.messageId;
console.log("messageId: ", messageId);
...
Get lastest version of node
And see this: https://firebase.google.com/docs/functions/database-events#handle_event_data for usage of onWrite(event...) and onCreate(.....)
That'll help you
Related
I have a cron job function running on Firebase functions, which fetches all documents from my User collection in Firestore, and sends notification using FCM to their devices. Due to limitations on how many tokens you can send to in one go, I'm splitting all my users tokens up in chunks of 100, and sending it in batches.
const admin = require("firebase-admin");
const fcm = admin.messaging();
const _ = require("lodash");
....
const deviceTokens = [.....] // <- flat array with all device tokens
const chunkedList = _.chunk(deviceTokens, 100); // [[...], [...], ...]
const message = "some message";
const sendAll = async () => {
const sendInChunks = chunkedList.map(async (tokenArr) => {
await fcm.sendToDevice(tokenArr, message);
});
await Promise.all(sendInChunks);
};
await sendAll();
I'm trying to understand from the documentation if this would be a safe way of doing it. For example, if one of the device tokens is stale or for some other reason fails, will that whole call to fcm.sendToDevice fail with along with the other tokens that was passed in, or will just that single device not recieve it? Or is there anything else I'm missing here?
Having one or more invalid/outdated tokens in the API call does not cause that call to fail.
Instead the FCM API (and its Admin SDK wrappers) will try to deliver each message separately and report back which specific tokens that you passed are unknown/outdated. You'll want to process those results and use them to prune your own token registry, similar to what this code sample in our Cloud Functions samples repro shows.
I am using firebase cloud function in my firebase group chat app, Setup is already done but problem is when some one send message in any group then all user get notification for that message including non members of group.
I want to send notification to group specific users only, below is my code for firebase cloud function -
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const _ = require('lodash');
admin.initializeApp(functions.config().firebase);
exports.sendNewMessageNotification = functions.database.ref('/{pushId}').onWrite(event => {
const getValuePromise = admin.database()
.ref('messages')
.orderByKey()
.limitToLast(1)
.once('value');
return getValuePromise.then(snapshot => {
const { text, author } = _.values(snapshot.val())[0];
const payload = {
notification: {
title: text,
body: author,
icon: ''
}
};
return admin.messaging()
.sendToTopic('my-groupchat', payload);
});
});
This will be really help full, if anyway some one can suggest on this.
As per our conversation on the comments I believe that the issue is that you are using a topic that contains all the users, which is the my-groupchat topic. The solution would be to create a new topic with the users that are part of this subtopic.
As for how to create such topics, there are a couple of examples in this documentation, in there you can see that you could do it server side, or client side. In your case, you could follow the examples for the server side, since you would need to add them in bulk, but as new users are added it could be interesting to implement the client side approach.
I am trying to send a message through discord.js and I am getting the following error:
(node:10328) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'send' of undefined
Here is my code:
// Init
const Discord = require("discord.js");
const bot = new Discord.Client();
const channel = bot.users.cache.get('4257');
// Vars
// Code
bot.on("ready", () => {
console.log("The Bot is ready!");
channel.send("Test");
});
// Login
bot.login(" "); // I will hide this.
What is wrong? Is it the id on the channel variable? I just put in the id of my bot since I didn't know what to put in it.
At first I gave it all the permissions under "Text Permissions", but I also tried giving him admin privs. It still didn't work. What am I doing wrong?
The problem is this line:
const channel = bot.users.cache.get('4257');
Here's what's wrong with it:
const channel = bot.users.cache // this returns a collection of users, you want channels.
.get('4257'); // this is a user discriminator, you want a channel ID
Here's how to fix it:
const id = <ID of channel you want to send the message to>
const channel = bot.channels.cache.get(id)
// ...
channel.send('Test')
Here's an example:
const channel = bot.channels.cache.get('699220239698886679')
channel.send('This is the #general channel in my personal Discord')
How to get a Channel ID
ChannelManager Docs
const channel is empty here. You need to make sure value should be assigned in it.
channel.send("Test");
If its not mendatory that value will come then use try-catch.
try {
channel.send("Test");
} catch(e) {
console.log(e)
}
Please support with vote or answered if it helps, thanks.
Having trouble sending a bot message on a specific channel. I very simply want to have the bot send a message to #general when it activates, to let everyone know it's working again.
In the bot.on function, I've tried the classic client.channels.get().send(), but the error messages I'm getting show that it thinks client is undefined. (It says "cannot read property 'channels' of undefined")
bot.on('ready', client => {
console.log("MACsim online")
client.channels.get('#general').send("#here");
})
The bot crashes immediately, saying: Cannot read property 'channels' of undefined
The ready event doesn't pass any client parameter.
To get a channel by name use collection.find():
client.channels.find(channel => channel.name == "channel name here");
To get a channel by ID you can simply do collection.get("ID") because the channels are mapped by their IDs.
client.channels.get("channel_id");
Here is an example I made for you:
const Discord = require("discord.js");
const Client = new Discord.Client();
Client.on("ready", () => {
let Channel = Client.channels.find(channel => channel.name == "my_channel");
Channel.send("The bot is ready!");
});
Client.login("TOKEN");
You need to get the guild / server by ID, and then the channel by ID, so your code will be something like :
const discordjs = require("discord.js");
const client = new discordjs.Client();
bot.on('ready', client => {
console.log("MACsim online")
client.guilds.get("1836402401348").channels.get('199993777289').send("#here");
})
Edit : added client call
The ready event does not pass a parameter. To gain the bot's client, simply use the variable that you assigned when you created the client.
From your code, it looks like the bot variable, where you did const bot = new Discord.Client();.
From there, using the bot (which is the bot's client), you can access the channels property!
I'm trying to send SMS using Twilio nodejs (with Typescript) but, for some reason, I cannot access to create method on messages property (as described in the documentation).
const TWILIO_CLIENT = require('twilio');
let twilioClient = new TWILIO_CLIENT(accountSid, authToken);
let result = await twilioClient.messages.create(smsData);
I get a undefined when trying to access create method, and when I log messages endpoint it only shows my the defined accountSid: { accountSid: "..." }
What could it be?