I am trying to implement device groups in my node.js file to trigger notifications.
I want to get the token_id and create a notification_key for the device groups for a single user.
but i am getting the error as.
ReferenceError: options is not defined
at Object.<anonymous> (D:\SweExpress\functions\index.js:13:9)
at Module._compile (internal/modules/cjs/loader.js:678:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)
at Module.require (internal/modules/cjs/loader.js:626:17)
at require (internal/modules/cjs/helpers.js:20:18)
at C:\Users\user\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:21:11
at Object.<anonymous> (C:\Users\user\AppData\Roaming\npm\node_modules\firebase-tools\lib\triggerParser.js:61:3)
and my index.js file is.
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
var request = require('request');
admin.initializeApp();
var headers = {
'Authorization': 'key = my service account key here',
'project_id': 'server_id',
'Content-Type': 'application/json'
}
request(options, function (error, response, body) {
console.log(body)
})
exports.sendNotification = functions.firestore.document("Users/ {user_id}/Notifications/{notification_id}").onWrite((change,context) => {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
return admin.firestore().collection("Users").doc(user_id).collection("Notifications").doc(notification_id).get().then(queryResult => {
const from_user_id = queryResult.data().from;
const from_message = queryResult.data().message;
const from_data = admin.firestore().collection("Users").doc(from_user_id).get();
const to_data = admin.firestore().collection("Users").doc(user_id).get();
return Promise.all([from_data, to_data]).then(result => {
const from_name = result[0].data().name;
const to_name = result[1].data().name;
const token_id = result[1].data().token_id;
var options = {
url: 'https://android.googleapis.com/gcm/notification',
method: 'POST',
headers: headers,
json: {'operation': 'create',
'notification_key_name': 'you#example.com',
'registration_ids': [token_id]}
}
request(options, function (error, response, body) {
console.log(body)
})
var notificationKey = body;
const payload = {
notification: {
title: "Notification From: " + from_name,
body : from_message,
icon : "notification.png",
sound: "orion.mp3"
}
};
return admin.messaging().sendToDeviceGroup(notificationKey,payload).then(result => {
var c = console.log("Notification sent ");
return c;
});
});
});
});
I am new to node.js as well.
Secondly, is my index.js file correct? or I am doing something wrong?.
Without initializing variable named option, your are passing it as a parameter for the request. Thats why you are getting following error ReferenceError: options is not defined. Here I commented the unused part. checkout this snippet now
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
var request = require('request');
admin.initializeApp();
var headers = {
'Authorization': 'key = my service account key here',
'project_id': 'server_id',
'Content-Type': 'application/json'
}
/* Code which causes error
request(options, function (error, response, body) {
console.log(body)
})*/
exports.sendNotification = functions.firestore.document("Users/ {user_id}/Notifications/{notification_id}").onWrite((change,context) => {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
return admin.firestore().collection("Users").doc(user_id).collection("Notifications").doc(notification_id).get().then(queryResult => {
const from_user_id = queryResult.data().from;
const from_message = queryResult.data().message;
const from_data = admin.firestore().collection("Users").doc(from_user_id).get();
const to_data = admin.firestore().collection("Users").doc(user_id).get();
return Promise.all([from_data, to_data]).then(result => {
const from_name = result[0].data().name;
const to_name = result[1].data().name;
const token_id = result[1].data().token_id;
var options = {
url: 'https://android.googleapis.com/gcm/notification',
method: 'POST',
headers: headers,
json: {'operation': 'create',
'notification_key_name': 'you#example.com',
'registration_ids': [token_id]}
}
request(options, function (error, response, body) {
console.log(body)
})
var notificationKey = body;
const payload = {
notification: {
title: "Notification From: " + from_name,
body : from_message,
icon : "notification.png",
sound: "orion.mp3"
}
};
return admin.messaging().sendToDeviceGroup(notificationKey,payload).then(result => {
var c = console.log("Notification sent ");
return c;
});
});
});
});
Your options object is defined after its first use:
request(options, function (error, response, body) {
console.log(body)
})
Define
var options = { ...
before it is used in
request(options ...
Hope that helps :)
Related
I am developing a Flutter Restful web application and the web api backend as asp.net core. When i try to send the form data using post request it is throwing this error
DioError [DioErrorType.RESPONSE]: Http status error [400] Exception
Code
onPressed: () async {
String email_value = emailController.text;
String password_value = passController.text;
String fullname_value = fullnameController.text;
var repassword_value = repassController.text;
print("$email_value");
if (password_value == repassword_value) {
try{
Dio dio = Dio();
var body = jsonEncode(
{
'FullName': '$fullname_value',
'Email': '$email_value',
'Password': '$password_value'
}
);
print("Body" + body);
Response response = await dio.post("http://iamtv.chainuniverse.com/api/Accounts/Register",
data: body,
options: Options(
contentType: Headers.jsonContentType,
)
);
var jsonData = json.decode(response.data);
print(jsonData);
if (response.statusCode > 200 &&
response.statusCode < 250) {
print("Sucess");
await loginAction();
print("Registered");
}
else{
print(jsonData);
}
But when i send data manually without using textcontroller Text it works. Please help me to fix this
Working perfectly in POSTMAN
Late answer, may help you.
I was getting same error with Dio and form-data. It worked! after adding contentType
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
complete code
var dio = Dio();
String fileName = imageFile.path.split('/').last;
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //add this
),
});
var response = await dio.post(
"url",
data: formData,
options: Options(
headers: {
"Authorization": auth-token
},
),
onSendProgress: (int sent, int total) {
debugPrint("sent${sent.toString()}" + " total${total.toString()}");
},
).whenComplete(() {
debugPrint("complete:");
}).catchError((onError) {
debugPrint("error:${onError.toString()}");
});
I am trying to send notifications to an Android app's users with firebase cloud messaging. I am using cloud firestore triggers but when trying to access a user node's properties, they are undefined.
Here is my index.js :
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.notifyNewMessage = functions.firestore
.document('conversations/{conversation}/messages/{message}')
.onCreate((docSnapshot, context) => {
const message = docSnapshot.data();
const recipientId = message['recipientId'];
const senderName = message['senderName'];
return admin.firestore().collection("users").doc(recipientId).get().then(userDoc => {
const registrationTokens = userDoc.registrationTokens;
console.log("registrationTokens = "+ registrationTokens);
const notificationBody = message['message'];
const payload = {
notification : {
title : senderName + " sent you a message,",
body: notificationBody,
clickAction: "ConversationActivity"
},
data : {
contactName : senderName,
userId : message['senderId']
}
}
return admin.messaging().sendToDevice(registrationTokens, payload).then(response => {
const stillRegisteredTokens = registrationTokens;
response.results.forEach((result, index) => {
const error = result.error;
if (error){
const failedRegistrationToken = stillRegisteredTokens['index'];
if (error.code === 'messaging/invalid-registration-token'
|| error.code === 'messaging/registration-token-not-registered') {
const failedIndex = stillRegisteredTokens.indexOf(failedRegistrationToken)
if (failedIndex > -1) {
stillRegisteredTokens.splice(failedIndex, 1);
}
}
}
})
return admin.firestore().doc("users/" + recipientId).update({
registrationTokens: stillRegisteredTokens
})
})
})
})
Because of that I get an error "sendDevice() argument must be non-empty array or non null string"
UPDATE
registrationTokens were undefined because I called userDoc instead of userDoc.data()
Now registrationTokens is not null nor empty but I still get the error :
Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array.
I have this code that works correctly but I want to add the 'mensaje' in the body of the notification, the problem is that I do not know how to get it to be able to send it.
This is the structure of my data in firebase:
enter image description here
And this is the function:
const functions = require('firebase-functions');
let admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendPush = functions.database.ref('/chats/{chat}/{mensaje}/').onWrite((snapshot, context) => {
nombreChat = context.params.chat;
return cargarUsuarios(nombreChat).then(usuarios => {
let tokens = [];
for (let user of usuarios){
if(user.token !== undefined){
console.log('User', "Usuario: " + user.nombre);
console.log('User token', "Token: " + user.token);
tokens.push(user.token);
}
}
let payload = {
notification:{
title:'Trado GO',
body: 'Has recibido un nuevo mensaje',
sound: 'default',
badge: '1'
}
};
return admin.messaging().sendToDevice(tokens, payload);
});
});
function cargarUsuarios(chat){
var arrayParticipantesChat = chat.split(',');
let dbRef = admin.database().ref('/usuarios');
let defer = new Promise((resolve, reject) => {
dbRef.once('value', (snap) => {
let data = snap.val();
let usuarios = [];
for (var property in data){
usu=data[property];
if(arrayParticipantesChat.includes(usu['nombre'])){
usuarios.push(data[property]);
}
}
resolve(usuarios);
}, (err) => {
reject(err);
});
});
return defer;
}
I have not more experience of Android and almost have no idea in javascript coding, I followed a tutorial to create a firebase function and now firebase function change beta to stable and my code is showing me error :
this is my code --->
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification = functions.database.ref('/notifications/{user_id}/{notification_id}').onWrite((change, context)=> {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
console.log('We have a notification from : ', user_id);
if (!event.data.exists()) {
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 : "in.tvac.akshaye.lapitchat_TARGET_NOTIFICATION"
},
data : {
from_user_id : from_user_id
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
console.log('This was the notification Feature');
});
});
});
});
and this is my database ---->
notifications
BOhvOUJG8sWgIyTD7JLuSOgfv9v1
aqTdCWJYfvQiw188MqldsDtlLFf2
-LLO14ghpMruZtqwK7CR from: "rrajSiL7SFd7WQydkA7jwxi26s63" type: "request"
-LLOQ2WsWHymJvdOxrx5 from: "rrajSiL7SFd7WQydkA7jwxi26s63" type: "request"
-LLfVM43o8Rt-1A55r28
-LLfxudlktvk3ysxvype
i am getting this error --->
ReferenceError: event is not defined
at exports.sendNotification.functions.database.ref.onWrite (/user_code/index.js:15:7)
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)
Please check if you have defined the event or not
I have a react-native app on Android and a backend server written in NodeJS + Express and I'm using multer to handle file uploads.
const multer = require('multer');
const mime = require('mime');
const crypto = require('crypto');
const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, config.uploads),
filename: (req, file, cb) => {
crypto.pseudoRandomBytes(16, (err, raw) => {
cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype));
});
}
});
const upload = multer({ storage });
const Router = require('express').Router;
const controller = require('./upload.controller');
const router = new Router();
const auth = require('./../../auth/auth.service');
router.post('/', [auth.isAuthenticated(), upload.any()], controller.create);
module.exports = router;
And on my react-native app I try to do like this:
ImagePicker.launchCamera(options, image => {
let { uri } = image
const API_URL = 'http://192.168.1.2:9000/api/uploads'
var form = new FormData();
form.append("FormData", true)
form.append("access_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU3YjgyZGQ2MTEwZDcwYmEwYjUxZjM5YyIsImlzTWVkaWMiOnRydWUsImlhdCI6MTQ3MTY4ODE1MiwiZXhwIjoxNDcxNzA2MTUyfQ.gPeql5g66Am4Txl1WqnbvOWJaD8srTK_6vihOJ6kFbY")
form.append("Content-Type", "image/jpg")
form.append('image', uri)
fetch(API_URL, {body: form, mode: "FormData", method: "post", headers: {"Content-Type": "multipart/form-data"}})
.then((response) => console.log(response))
.catch((error) => {
console.log("ERROR " + error)
})
.then((responseData) => {
console.log("Succes "+ responseData)
})
.done();
})
But when I try to upload I recive the following error
multipart body must have at least one part
I am doing something wrong?
Does anybody knows a better solution to do this?
Fetch may not support Blob and FormData at this moment, but you can use XMLHttpRequest polyfill instead.
let xhr = new XMLHttpRequest()
xhr.open('post', `http://myserver.com/upload-form`)
xhr.send(form)
xhr.onerror = function(e) {
console.log('err', e)
}
xhr.onreadystatechange = function() {
if(this.readyState === this.DONE) {
console.log(this.response)
}
}