Messaging with XMPP
Send and receive FCM messages directly between devices & your server with a XMPP server.
Introduction
This is a reference for using the Firebase Messaging service to send and receive messages directly between devices. Although methods (e.g. sendMessage()
) are provided for sending and receiving message, additional configuration is needed to ensure a working solution for direct messaging from devices.
A custom solution is only required if plan to exchange messages directly between devices (including the message sender device) please ensure a solution from this article has been configured to successfully send and receive messages from a device.
The following describes how to set up a server to handle messages, including...
- A custom XMPP server with XCS for receiving messages.
- Firebase admin for sending messages.
So what are we going to do?
- Send a message from a client device.
- Intercept using a custom XMPP server.
- Push the message to Firebase using firebase-admin
- Receive the message and acknowledge on other connected devices.
Why can't I send and receive messages?
A common instance involves an implementation similar to the following.
firebase.messaging().onMessage(message => {
console.log('Received a message');
});
firebase.messaging().onMessageSent(message => {
console.log('Sent a message');
});
firebase.messaging().onSendError(message => {
console.log('Received an Error');
});
firebase.messaging().sendMessage({
data: {
foo: 'bar',
},
});
Although correct, none of the listeners will acknowledge a message
or error
.
Permissions are limited on the client meaning an additional solution is required to communicate between FCM
and any connected devices.
How do I receive messages?
This is where you will need to deploy a custom server based, for example one based on Node XCS
Below is an example of how to configure a custom XMPP server using node-xcs
.
const Sender = require('node-xcs').Sender;
async function operation() {
return () => {
console.log('Listening >>>');
// Enter firebase credentials here. {SenderID, ServerKey}
var xcs = new Sender('XXXXXXXX', 'XXXXXXXX');
xcs.start();
xcs.on('message', function (messageId, from, data, category) {
console.log('received message', messageId, from, data, category);
});
xcs.on('receipt', function (messageId, from, data, category) {
console.log('received receipt', arguments);
});
xcs.on('error', e => console.warn('XMPP error.', e));
};
}
async function app() {
await operation();
}
app();
How do I send messages?
For sending messages we can use the Firebase Admin SDK.
const admin = require('firebase-admin');
const serviceAccount = require('./service-account.json');
(async () => {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'XXXXXXXX',
});
await admin.messaging().send({
token: 'XXXXXXX',
data: {
foo: 'bar',
},
});
})();