Getting these errors on firebase cloud messaging - node.js

This is the error shown while using firebase messaging for push notifications...
Error: Exactly one of topic, token or condition is required
at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
Error: Exactly one of topic, token or condition is required
at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16)
at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15)
at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:208:27)
at sendNotification (/srv/index.js:227:18)
at exports.onCreateActivityFeedItem.functions.firestore.document.onCreate (/srv/index.js:197:13)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
This is the js code for firebase messaging
exports.onCreateActivityFeedItem = functions.firestore
.document('/feed/{userId}/feedItems/{activityFeedItem}')
.onCreate(async (snapshot, context) => {
console.log('Activity Feed Item Created', snapshot.data());
This log is printed...
// 1) Get user connected to the feed,
//send notification if they have token
const userId = context.params.userId;
const userRef = admin.firestore().doc(`users/${userId}`);
const doc = await userRef.get();
// 2) Once we have user check if they have notification item
const androidNotificationToken = doc.data().androidNotificationToken;
const createdActivityFeedItem = snapshot.data();
if (androidNotificationToken) {
// send notification
sendNotification(androidNotificationToken, createdActivityFeedItem);
} else {
console.log('User have no token, cant send notification');
}
function sendNotification(androidNotificationToken, activityFeedItem) {
let body;
// switch bod y value base on notification item (like, comment or follow)
switch (activityFeedItem.type) {
case 'comment':
body = `${activityFeedItem.username} replied: ${activityFeedItem.commentData}`;
break;
case 'like':
body = `${activityFeedItem.username} liked your post.`;
case 'follow':
body = `${activityFeedItem.username} followed you.`;
default:
break;
}
// 4) create message for push notification
const message = {
notification: { body },
token: { androidNotificationToken },
data: { recipient: userId }
};
// 5) send message with admin.messaging
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);
});
}
});
This is Flutter code
configurePushNotifications() {
final GoogleSignInAccount user = googleSignIn.currentUser;
if (Platform.isIOS) {
getIOSPermission();
}
_firebaseMessaging.getToken().then((token) {
print('Token received: $token');
usersRef.document(user.id).updateData({
'androidNotificationToken': token,
});
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('Message is : $message');
final String recipientId = message['data']['recipient'];
final String body = message['notification']['body'];
if (recipientId == user.id) {
print('Notification Shown');
SnackBar snackbar = SnackBar(
content: Text(
body,
overflow: TextOverflow.ellipsis,
),
);
_scaffoldKey.currentState.showSnackBar(snackbar);
}
print('Notification not shown');
},
// onResume: (Map<String, dynamic> message) async {},
// onLaunch: (Map<String, dynamic> message) async {},
);
});
}
To get ios permission but i am using android phone for debugging
getIOSPermission() {
_firebaseMessaging.requestNotificationPermissions(
IosNotificationSettings(
alert: true,
badge: true,
sound: true,
),
);
_firebaseMessaging.onIosSettingsRegistered.listen((settings) {
print('Settings registered: $settings');
});
}
onCreateActivityFeedItem
Activity Feed Item Created { commentData: 'ab to man ja', mediaUrl: 'https://firebasestorage.googleapis.com/v0/b/chautari-ccfba.appspot.com/o/post_dcc8a054-a972-4b88-8d3f-4802de74393a.jpg?alt=media&token=1120cadb-14cb-4173-a4ec-775290f68fc8', postId: 'dcc8a054-a972-4b88-8d3f-4802de74393a', timeStamp: Timestamp { _seconds: 1589793598, _nanoseconds: 111000000 }, type: 'comment', userId: '116659062086341253410', userProfileImage: 'https://firebasestorage.googleapis.com/v0/b/chautari-ccfba.appspot.com/o/post_profile_pic_postId%3A116659062086341253410.jpg?alt=media&token=8da521ea-2a5e-4833-93b7-9a487afb7be5', username: 'rishi' }
3:23:55.242 PM
onCreateActivityFeedItem
Error: Exactly one of topic, token or condition is required
at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28)
at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16)
at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15)
at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:208:27)
at sendNotification (/srv/index.js:227:18)
at exports.onCreateActivityFeedItem.functions.firestore.document.onCreate (/srv/index.js:197:13)
at
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
3:23:55.258 PM
onCreateActivityFeedItem

The error seems to come from the JavaScript code. More precisely, this seems off:
const message = {
notification: { body },
token: { androidNotificationToken },
data: { recipient: userId }
};
If you look at the Firebase documentation on sending a message it contains this example:
var message = {
data: {
score: '850',
time: '2:45'
},
token: registrationToken
};
You are wrapping the token in an extra {}, which is not correct as it leads to this JSON: token: { androidNotificationToken: "valueOfandroidNotificationToken" }.
More likely it needs to be:
const message = {
notification: { body },
token: androidNotificationToken,
data: { recipient: userId }
};

Related

Razorpay not returning payment_id,order_id etc. upon successfull payment

I have one function that is responsible of creating order using razorpay and verify that order .
The code for that function is : -
const paymentMethod = async ()=>{
if(!isAuthenticated())
{
toast.error('Please signin to continue');
history.push('/signin')
// return <Redirect to='/signin' />
return;
}
try{
// console.log(JSON.stringify(total));
const obj = {
amount:total
}
let data = await fetch('http://localhost:3100/api/checkout',{
method:'POST',
headers:{
"content-type":"application/json",
Accept:"application/json"
},
body: JSON.stringify(obj)
})
let {order} = await data.json()
console.log(order)
console.log(order.amount)
const options = {
key: "rzp_test_cXj3ybg8fawS9Y",
amount: order.amount,
currency: "INR",
name: "YO! Merchandise",
description: "Pay Please",
image:yo,
order_id: order.id,
callback_url: "http://localhost:3100/api/paymentverification",
prefill: {
name: "Aakash Tiwari",
email: "tiwaryaakash00#gmail.com",
contact: "8750043604"
},
notes: {
address: "Razorpay Corporate Office"
},
theme: {
color: "#13C962"
}
};
let rzp1 = await new window.Razorpay(options);
rzp1.open();
}
catch(err){
console.log(err)
}
}
But this function when call callback_url upon successfull payment it is not passing the payment_id,order_id etc. other neccessary details.
when i try to console.log there the req.body is always empty.

createAysncThunk in Redux Toolkit catching error when making fetch request

I'm working on the user registration functionality of an application using Typescript and Redux Toolkit. When I make the fetch request to the signup endpoint, a new user is saved to the database I've connected, but I keep entering the catch error block.
export const registerUser = createAsyncThunk(
"user/registerUser",
async (form: { username:string, password:string }, thunkAPI) => {
try {
const response = await fetch('/api/auth/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userInfo: {
username: form.username,
password: form.password
}
}),
});
if (response.status === 200) return 200;
else return 400;
} catch (e) {
console.log('Error')
}
}
);
I've tried logging the response to the console a number of ways
const data = await response.json() console.log(data)
But have had no luck. I think this is an error with how I've done my fetch request using createAsyncThunk but haven't been able to figure out what I've missed.
This is the code for the initial state and slice:
interface UserState {
userProfile: {
id: number | null;
},
registration: {
status: 'loaded' | 'loading'
}
}
const initialState : UserState = {
userProfile: {
id: null,
},
registration: {
status: 'loaded'
}
};
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
},
extraReducers: (builder) => {
builder.addCase(registerUser.fulfilled, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.rejected, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.pending, (state) => { state.registration.status = 'loading' })
}
})
And here is the code for the function where the action is dispatched on the UI
const handleRegister= async () => {
if (!username) return alert('Username field was left empty');
if (!password) return alert('Password field was left empty');
const {payload} : any = await dispatch(registerUser({ username: username, password: password}));
if (payload === 200) {
alert('Successfully registered. Redirecting to dashboard');
return navigate('/dashboard');
} else { return alert('User creation unsuccessful'); }
}
Appreciate any help as I've looked through many other posts but haven't been able to resolve my issue.

gmail api auth issue - cannot get attachment from the chosen email

I'm working with node.js v13 with Gmail api.
I have done successfully getting the specific email message and now I'm trying
to get the attachment from that same email.
function getRecentEmail(auth) {
// Only get the recent email - 'maxResults' parameter
gmail.users.messages.list({ auth: auth, userId: 'me', maxResults: 1, q: 'subject:pokerrrr' }, function (
err,
response
) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
// Get the message id which we will need to retreive tha actual message next.
const message_id = response['data']['messages'][0]['id'];
// Retreive the actual message using the message id
gmail.users.messages.get({ auth: auth, userId: 'me', id: message_id }, function (err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
// const attachment_id = response['data'].payload.parts[1].body.attachmentId;
const message = response['data'];
// getAttachments('me', message, auth);
const parts = message.payload.parts;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (part.filename && part.filename.length > 0) {
const attachId = part.body.attachmentId;
gmail.users.messages.attachments.get(
{
id: attachId,
messageId: message.id,
userId: 'me',
},
function (attachment) {
// saveAttachmentsToDir(part.filename, part.mimeType, attachment);
}
);
}
}
});
});
}
when I run the code above, the attachment parameter is showing me auth error and I cant understand why.
here is the error:
code:401
config:Object {url: "https://www.googleapis.com/gmail/v1/users/me/messa…", method: "GET", paramsSerializer: , …}
errors:Array(1) [Object]
message:"Login Required"
response:Object {config: Object, data: Object, headers: Object, …}
stack:"Error: Login Required
at Gaxios.<anonymous> (c:\Users\tomer\Desktop\Mail listener -tomer\Mail listener\node_modules\gaxios\build\src\gaxios.js:73:27)
at Generator.next (<anonymous>)
at fulfilled (c:\Users\tomer\Desktop\Mail listener -tomer\Mail listener\node_modules\gaxios\build\src\gaxios.js:16:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)"
__proto__:Error {constructor: }

Serverless notifications with Cloud Functions for Firebase

I have used firebase chat notification cloud function but when
notification triggered I am getting this error in firebase function
console
Cannot read property 'current' of undefined
at exports.sendNotification.functions.database.ref.onWrite.event (/user_code/index.js:8:35)
Here is my function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/notifications/messages/{pushId}').onWrite(event => {
console.log('Push notification event triggered for testing');
console.log(event);
const message = event.data.current.val();
const senderUid = message.from;
const receiverUid = message.to;
console.log(receiverUid);
const promises = [];
if (senderUid === receiverUid) {
//if sender is receiver, don't send notification
promises.push(event.data.current.ref.remove());
return Promise.all(promises);
}
const getInstanceIdPromise = admin.database().ref(`/usersnew/${receiverUid}`).once('value');
const getSenderUidPromise = admin.auth().getUser(senderUid);
return Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results => {
const instanceId = results[0].val();
const sender = results[1];
console.log('notifying ' + receiverUid + ' about ' + message.body + ' from ' + senderUid);
const payload = {
notification: {
title: sender.displayName,
body: message.body,
icon: sender.photoURL
}
};
admin.messaging().sendToDevice(instanceId, payload)
.then(function (response) {
return console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
return console.log('This is the notify feature');
});
});
Does anyone know how to solve this?
When I log event it shows like below in console
{ before:
DataSnapshot {
app:
FirebaseApp {
firebaseInternals_: [Object],
services_: {},
isDeleted_: false,
name_: '__admin__',
options_: [Object],
INTERNAL: [Object] },
instance: 'https://teleport-24f52.firebaseio.com',
_path: '/notifications/messages/-LIlFNd2spo_V1rM-G-f',
_data: null },
after:
DataSnapshot {
app:
FirebaseApp {
firebaseInternals_: [Object],
services_: {},
isDeleted_: false,
name_: '__admin__',
options_: [Object],
INTERNAL: [Object] },
instance: 'https://teleport-24f52.firebaseio.com',
_path: '/notifications/messages/-LIlFNd2spo_V1rM-G-f',
_data:
{ body: 'abc',
dayTimestamp: 1532975400000,
from: 'q8gtwtwXqbV2DtpsrbYajFsWzSr2',
negatedTimestamp: -1533056068309,
timestamp: 1533056068309,
to: 'Cmpu7mbIENTYyoHZjCjZnbnBMbl2' } } }
10:22:44.625 PM
In your code, event.data.current should be event.after.val() , event.after.ref, etc...
There was a change of API in cloud functions 1.0.
Read:
https://firebase.google.com/docs/functions/database-events#reading_the_previous_value
https://firebase.google.com/docs/functions/beta-v1-diff
Maybe the problem is in the SDK version. From v1.0 things change a bit. Try updating SDK and follow these instructions for miragation:
https://firebase.google.com/docs/functions/beta-v1-diff

Push notification returns ECONNRESET in Google Cloud Functions

I am having a function in Firebase Cloud Functions that is retrieves the user's device group id in order to send a push notification, and after sends a push notification. This works well if the function gets called only once, but if I have an array of users I want to send a push notification too, the sendPushNotification function returns error : FAILED err= { RequestError: Error: read ECONNRESET
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15) for every try to send push
From what i understand ECONNRESET means that the connection gets closed at one end before finishing the operation, can some help/explain me why this is:
here is my code:
function sendFollowNotification(snapshot) {
const notificationMsg = getFollowNotificationMsg() //returns a string
snapshot.forEach(function(singleUser, index) {
const userId = singleUser.key;
const userObject = singleUser.val();
console.log("will get device group")
if (index + 1 == snapshot.numChildren()) {
return getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", true);
} else {
getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", false);
}
}
function getDeviceGroupNotificationKey(groupId, notificationTitle, notificationBody, notificationSubject, shouldReturn) {
const pathToDeviceGroup = admin.database().ref('deviceGroups').child(groupId);
pathToDeviceGroup.once("value").then( function(snapshot) {
const deviceGroupObj = snapshot.val();
const notification_key = deviceGroupObj.notification_key;
console.log("got notification key")
console.log(notification_key)
if (notification_key !== undefined) {
return sendPushToDeviceGroupOld(notification_key, notificationTitle, notificationBody, "notificationKeyOld2", notificationSubject, shouldReturn);
} else {
return
}
}).catch(reason => {
console.log("user device group not there")
return
})
}
function sendPushToDeviceGroupOld(notification_key, title, body, subject, message, shouldReturn) {
console.log('sending push to ' + notification_key)
const serverKey = '-';
const senderId = '-';
const options = {
method: 'POST',
uri: 'https://fcm.googleapis.com/fcm/send',
headers: {
'Authorization': 'key=' + serverKey,
'project_id': senderId
},
body: {
to: notification_key,
data: {
subject: message
},
notification: {
title: title,
body: body,
badge: 1,
sound: "default",
},
priority : 'high',
content_available: true
},
json: true
};
return rqstProm(options)
.then((parsedBody) => {
console.log('SUCCESS response=', parsedBody);
return
})
.catch((err) => {
console.log('FAILED', err);
return
});
}

Resources