Why am I not receiving firebase messages? - javascript

I see my server is sending correctly the messages to firebase API since it returns a success: 1 response but my client is not receiving the messages, what is happening, my code is:
const messaging = firebase.messaging()
const that = this
messaging.requestPermission()
.then(function() {
return messaging.getToken()
})
.then(function(token) {
that.updateServerFirebaseToken(token)
})
.catch(function(err) {
console.log(err)
})
// Call to user
messaging.onMessage(function(payload) {
console.log('firebase', payload)
if(payload.data.status == 'calling') {
this.audio.play()
this.$store.commit(types.CALLING, JSON.decode(payload.data.order))
}
})
and my service worker firebase-messaging-sw.js
const messaging = firebase.messaging()
messaging.setBackgroundMessageHandler(function(payload) {
console.log('FIREBASE call', payload);
if(payload.data.status == 'calling') {
channel.postMessage(payload.data)
return self.registration.showNotification('Nuevo pedido', {body: "Llamada para transporte de un pedido"})
}
})

Related

Javascript if conditional variable problem

I have two receiver type. 0 for guests 1 for users. I'm trying to push notification from firebase cloud functions. I can send notification user to guest succesfully. But can not send notification guest to user. Is there any problem with my if condition?
var usersRef = null;
if (receiverType === 0) {
usersRef = admin.firestore().collection('Guests').doc(receiverId);
} else {
usersRef = admin.firestore().collection('Users').doc(receiverId);
}
I want to change var usersRef variable based on receiverType. I managed to change it to Guest path but on the else part its path must change again to Users. But not changing. There is a problem in my if else statement.
var getDoc = usersRef.get()
.then(doc => {
if (!doc.exists) {
return null;
} else {
const token = doc.data().token;
const payload = {
notification: {
title: "New Message",
body: chatMessage,
}
};
admin.messaging().sendToDevice(token, payload)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
return null;
})
.catch((error) => {
console.log('Error sending message:', error);
return null;
});
}
return null;
})
.catch(err => {
console.log('Error getting document', err);
return null;
});
return null;
});

High Delay in FCM when sent through Firebase Functions

I'm trying to send FCM using Firebase Functions, This is the code I'm using
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
admin.firestore().settings({
timestampsInSnapshots: true
});
var token = 'token_value';
var sender = 'sender_value';
var reciever = 'reciever_value';
var message = 'message_value';
var payload ='payload_value';
var db = admin.firestore();
exports.sendFollowerNotification =
functions.database.ref('/m/{messageid}')
.onCreate((snapshot, context) => {
console.log('v21');
message = context.params.messageid;
console.log('Message Id:', message);
reciever = snapshot.val().r;
console.log('Message reciever: ', reciever);
sender = snapshot.val().s;
console.log('Message sender: ', sender);
payload = {
data: {
id: `${message}`,
sender: `${sender}`
}
};
console.log('Payload Created');
var tokenRef = db.collection(reciever).doc('t');
console.log('Fetching Token');
tokenRef.get()
.then(doc => {
console.log('Fetching Token started');
if (!doc.exists) {
console.log('Token doesnt exist ');
} else {
token = doc.data().v;
console.log('Token data:', token);
}
console.log('End Then');
return token;
})
.catch(err => {
console.log('Error getting token', err);
}).then((token) => {
console.log('Sending FCM now');
admin.messaging().sendToDevice(token,payload);
return console.log('Successfully sent message:');
})
.catch((error) => {
console.log('Error sending message:', error);
});
})
The problem is that FCM is received with huge delay(about 40s), however fcm sent from Firebase Console is received almost immediately (about 2-3s).
Since I am an android developer and have no experience of Node.js, I believe that something is wrong with JS code. Help me by telling whats wrong or possible workaround.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
admin.firestore().settings({
timestampsInSnapshots: true
});
var db = admin.firestore();
function debugLogger(msg) {
// comment out to disable logging
console.log(msg);
}
function errLogger(err) {
console.log(err);
}
exports.sendFollowerNotification =
functions.database.ref('/m/{messageid}')
.onCreate((snapshot, context) => {
debugLogger('v23_stackoverflow');
const message = context.params.messageid;
debugLogger(`Message Id: ${message}`);
const reciever = snapshot.val().r;
debugLogger(`Message reciever: ${reciever}`);
const sender = snapshot.val().s;
debugLogger(`Message sender: ${sender}`);
const payload = {
data: {
id: `${message}`,
sender: `${sender}`
}
};
debugLogger('Payload Created');
let tokenRef = db.collection(reciever).doc('t');
debugLogger('Fetching Token');
return tokenRef.get()
.then(doc => {
debugLogger('Fetching Token started');
if (!doc.exists)
throw new Error("Token doesnt exist");
let token = doc.data().v;
debugLogger(`Token data: ${token}`);
return token;
})
.then(token => {
debugLogger('Sending FCM now');
return admin.messaging().sendToDevice(token, payload);
})
.then(() => {
debugLogger('Successfully sent message!');
return null;
})
.catch(err => {
errLogger(err);
})
})

Better error handling with Promises?

I am currently experimenting Google Firebase functions to access Google APIs. It's running fine, but I am a little bit lost in trying to manage the errors that could be detected ...
In the .HTTPS getGoogleUsers functions , I would like to return an HTTP status code ( 200 or error code ) , and the data ( or error message )
As far as I can see , I can get errors:
from the connect() function ( 500: Internal server error or 401 Unauthorized )
from the listUsers() function ( 500: Internal server error or 400 Bad Request )
Am I totally or partially wrong ? what should be my strategy in this case ?
thanks for feedback ..
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const {google} = require('googleapis');
const KEY = require('./service-key.json');
// Create JSON Web Token Client
function connect () {
return new Promise((resolve, reject) => {
const jwtClient = new google.auth.JWT(
KEY.client_email,
null,
KEY.private_key,
['https://www.googleapis.com/auth/admin.directory.user'],
'adminuser#mydomain.com'
);
jwtClient.authorize((err) => {
if(err) {
reject(err);
} else {
resolve(jwtClient);
}
});
});
}
function listUsers (client) {
return new Promise((resolve, reject) => {
google.admin('directory_v1').users.list({
auth: client,
domain: 'mydomain.com',
}, (err, response) => {
if (err) {
reject(err);
}
resolve(response.data.users);
});
});
}
function getAllUsers () {
connect()
.then(client => {
return listUsers(client);
})
.catch(error => {
return error;
})
}
exports.getGoogleUsers = functions.https.onRequest((req, res) => {
const users = getAllUsers();
if (error) {
status = error.status;
data = error.message;
} else {
status = 200;
data = users;
}
res.send({ status: status, datas: data })
});
I think you are looking for
function getAllUsers () {
return connect().then(listUsers);
//^^^^^^
}
exports.getGoogleUsers = functions.https.onRequest((req, res) => {
getAllUsers().then(users => {
return {status: 200, datas: users};
}, error => {
return {status: error.status, datas: error.message};
}).then(response => {
res.send(response);
});
});
This uses the .then(…, …) method with two callbacks to distinguish between success and error case, and to wait for the result of the promise.

Inconsistent results from Firestore Cloud Functions

I have a Cloud Function setup on Firebase that involved checking different parts of the Firestore Database and then sending a message via Cloud Messaging
Below is the JavaScript for the function in question:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().Firebase);
var db = admin.firestore();
exports.newMemberNotification = functions.firestore
.document('Teams/{teamId}/Waitlist/{userId}').onDelete((snap, context) => {
// get the user we want to send the message to
const newValue = snap.data();
const teamidno = context.params.teamId;
const useridno = newValue.userID;
//start retrieving Waitlist user's messaging token to send them a message
var tokenRef = db.collection('Users').doc(useridno);
tokenRef.get()
.then(doc => {
if (!doc.exists) {
console.log('No such document!');
} else {
const data = doc.data();
//get the messaging token
var token = data.messaging_token;
console.log("token: ", token);
//reference for the members collection
var memberRef = db.collection('Teams/'+teamidno+' /Members').doc(useridno);
memberRef.get()
.then(doc => {
if (!doc.exists){
console.log('user was not added to team. Informing them');
const negPayload = {
data: {
data_type:"team_rejection",
title:"Request denied",
message: "Your request to join the team has been denied",
}
};
return admin.messaging().sendToDevice(token, negPayload)
.then(function(response){
console.log("Successfully sent rejection message:", response);
return 0;
})
.catch(function(error){
console.log("Error sending rejection message: ", error);
});
} else {
console.log('user was added to the team. Informing them')
const payload = {
data: {
data_type: "team_accept",
title: "Request approved",
message: "You have been added to the team",
}
};
return admin.messaging().sendToDevice(token, payload)
.then(function(response){
console.log("Successfully sent accept message:", response);
return 0;
})
.catch(function(error){
console.log("Error sending accept message: ", error);
});
}
})
.catch(err => {
console.log('Error getting member', err);
});
}
return 0;
})
.catch(err => {
console.log('Error getting token', err);
});
return 0;
});
The issues I have with this are:
The code runs and only sometimes actually checks for the token or sends a message.
the logs show this error when the function runs: "Function returned undefined, expected Promise or value " but as per another Stack Oveflow posts, I have added return 0; everywhere a .then ends.
I am VERY new to node.js, javascript and Cloud Functions so I am unsure what is going wrong or if this is an issue on Firebase's end. Any help you can give will be greatly appreciated
As Doug said, you have to return a promise at each "step" and chain the steps:
the following code should work:
exports.newMemberNotification = functions.firestore
.document('Teams/{teamId}/Waitlist/{userId}').onDelete((snap, context) => {
// get the user we want to send the message to
const newValue = snap.data();
const teamidno = context.params.teamId;
const useridno = newValue.userID;
//start retrieving Waitlist user's messaging token to send them a message
var tokenRef = db.collection('Users').doc(useridno);
tokenRef.get()
.then(doc => {
if (!doc.exists) {
console.log('No such document!');
throw 'No such document!';
} else {
const data = doc.data();
//get the messaging token
var token = data.messaging_token;
console.log("token: ", token);
//reference for the members collection
var memberRef = db.collection('Teams/' + teamidno + '/Members').doc(useridno);
return memberRef.get()
}
})
.then(doc => {
let payload;
if (!doc.exists) {
console.log('user was not added to team. Informing them');
payload = {
data: {
data_type: "team_rejection",
title: "Request denied",
message: "Your request to join the team has been denied",
}
};
} else {
console.log('user was added to the team. Informing them')
payload = {
data: {
data_type: "team_accept",
title: "Request approved",
message: "You have been added to the team",
}
};
}
return admin.messaging().sendToDevice(token, payload);
})
.catch(err => {
console.log(err);
});
});

Chrome not receiving fcm messages, but firefox does

I am using FCM to facilitate push messages in a custom service worker. I followed the FCM getting started but am running into issues where the javascript client isn't receiving the sent messages on chrome, but firefox is working as intended.
The messages are being sent from a hosted server, and the messages are sent with no failures and message id's associated with each registered client.
Below is the page script and below that will be relevant service worker code.
page html
<script>
// Initialize Firebase
var config = {
<CONFIG SETTINGS>
};
firebase.initializeApp(config);
var messaging = firebase.messaging();
</script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js').then(function (registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
messaging.useServiceWorker(registration);
resetUI();
}).catch(function (err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
const permissionDivId = 'permission_div';
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (refreshedToken) {
console.log('Token refreshed.');
setTokenSentToServer(false);
sendTokenToServer(refreshedToken);
resetUI();
})
.catch(function (err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
messaging.onMessage(function (payload) {
console.log("Message received. ", payload);
appendMessage(payload);
});
function resetUI() {
clearMessages();
messaging.getToken()
.then(function (currentToken) {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
updateUIForPushPermissionRequired();
setTokenSentToServer(false);
}
})
.catch(function (err) {
console.log('An error occurred while retrieving token. ', err);
setTokenSentToServer(false);
});
}
function sendTokenToServer(currentToken) {
if (!isTokenSentToServer()) {
console.log('Sending token to server...');
<TOKEN SENT TO SERVER AND STORED>
setTokenSentToServer(true);
} else {
console.log('Token already sent to server so won\'t send it again ' +
'unless it changes');
}
}
function isTokenSentToServer() {
if (window.localStorage.getItem('sentToServer') == 1) {
return true;
}
return false;
}
function setTokenSentToServer(sent) {
window.localStorage.setItem('sentToServer', sent ? 1 : 0);
}
function showHideDiv(divId, show) {
const div = document.querySelector('#' + divId);
if (show) {
div.style = "display: visible";
} else {
div.style = "display: none";
}
}
function requestPermission() {
console.log('Requesting permission...');
messaging.requestPermission()
.then(function () {
console.log('Notification permission granted.');
resetUI();
})
.catch(function (err) {
console.log('Unable to get permission to notify.', err);
});
}
function deleteToken() {
messaging.getToken()
.then(function (currentToken) {
messaging.deleteToken(currentToken)
.then(function () {
console.log('Token deleted.');
setTokenSentToServer(false);
resetUI();
})
.catch(function (err) {
console.log('Unable to delete token. ', err);
});
})
.catch(function (err) {
console.log('Error retrieving Instance ID token. ', err);
});
}
// Add a message to the messages element.
function appendMessage(payload) {
const messagesElement = document.querySelector('#messages');
const dataHeaderELement = document.createElement('h5');
const dataElement = document.createElement('pre');
dataElement.style = 'overflow-x:hidden;'
dataHeaderELement.textContent = 'Received message:';
dataElement.textContent = JSON.stringify(payload, null, 2);
messagesElement.appendChild(dataHeaderELement);
messagesElement.appendChild(dataElement);
}
// Clear the messages element of all children.
function clearMessages() {
const messagesElement = document.querySelector('#messages');
while (messagesElement.hasChildNodes()) {
messagesElement.removeChild(messagesElement.lastChild);
}
}
function updateUIForPushEnabled(currentToken) {
showHideDiv(permissionDivId, false);
}
function updateUIForPushPermissionRequired() {
showHideDiv(permissionDivId, true);
}
</script>
sw.js
self.addEventListener('push', function (event) {
console.log('Service Worker recived a push message', event.data.text());
var notification = event.data.json().notification;
var title = notification.title;
event.waitUntil(
self.registration.showNotification(title, {
body: notification.body,
icon: notification.icon,
data: { url: notification.click_action }
}));
});
Thank you for any help you can give!

Categories

Resources