Reputation: 61
I have a simple chat webapp where two people can talk to each other. I want them to get notifications when they get a new message. So far I managed to get the permission from the user and also got the token:
const messaging = firebase.messaging();
function InitializeFirebaseMessaging(){
messaging.requestPermission().then(function(){
console.log("Notification permission");
return messaging.getToken();
}).then(function(token){
console.log("Token: "+token);
}).catch(function (reason){
console.log(reason);
});
}
messaging.onMessage(function (payload){
console.log(payload);
});
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (newtoken) {
console.log("New Token : "+ newtoken);
})
.catch(function (reason) {
console.log(reason);
})
});
In the Firestore I have a "pairings" collection where I have paired up users (so only pairs can send messages to each other) and there is a collection for each user with their sent and received messages.
When I log into Firebase, go to Engage/Cloud Messaging, I can send a message to that user from Firebase using the token. How can I achieve sending notifications automatically to the other person for each incoming message?
Upvotes: 0
Views: 1223
Reputation: 7388
If you want to send messages automatically you would need to setup a cloud function listener for new messages for each chat. When a new messages is written use that cloud function to send an FCM message to the user receiving the message.
Here is an example how I do it in one of my apps using a RTDB listener:
import * as functions from 'firebase-functions'
import admin from 'firebase-admin'
export default functions
.region('europe-west1')
.database.ref('/user_chat_messages/{senderUid}/{receiverUid}/{messageUid}')
.onCreate(async (eventSnapshot, context) => {
const { timestamp, params } = context
const { senderUid, receiverUid, messageUid } = params
if (context.authType === 'ADMIN') {
return null
}
const snapValues = eventSnapshot.val()
const {
message = '',
link,
image,
location,
audio,
authorUid,
created,
authorPhotoUrl,
} = snapValues
let lastMessage = message
const senderRef = admin.database().ref(`/users/${senderUid}`).once('value')
const senderSnap = await admin
.database()
.ref(`/users/${senderUid}`)
.once('value')
const receiverSnap = await admin
.database()
.ref(`/users/${receiverUid}`)
.once('value')
const {
displayName: senderName = null,
photoURL: senderPhoto = null,
} = senderSnap.val()
const {
displayName: receiverName = null,
photoURL: receiverPhoto = null,
} = receiverSnap.val()
if (!message) {
if (link) {
lastMessage = 'Link'
}
if (image) {
lastMessage = 'Photo'
}
if (location) {
lastMessage = 'Position'
}
if (audio) {
lastMessage = 'Audio'
}
}
// receiver chat message
await admin
.database()
.ref(`/user_chat_messages/${receiverUid}/${senderUid}/${messageUid}`)
.update(snapValues)
// sender chat message
await admin
.database()
.ref(`/user_chat_messages/${senderUid}/${receiverUid}/${messageUid}`)
.update({
isSend: timestamp,
})
// sender chat
await admin
.database()
.ref(`/user_chats/${senderUid}/${receiverUid}`)
.update({
unread: 0,
displayName: receiverName,
photoURL: receiverPhoto,
lastMessage: lastMessage,
authorUid: senderUid,
lastCreated: created,
isSend: timestamp,
isRead: null,
})
// receiver chat
await admin
.database()
.ref(`/user_chats/${receiverUid}/${senderUid}`)
.update({
displayName: senderName,
photoURL: senderPhoto,
authorUid: senderUid,
lastMessage: lastMessage,
lastCreated: created,
isRead: null,
})
// update unread
await admin
.database()
.ref(`/user_chats/${receiverUid}/${senderUid}/unread`)
.transaction((number) => {
return (number || 0) + 1
})
if (authorUid !== receiverUid) {
const messages = []
const payload = {
notification: {
title: `${snapValues.authorName}`,
body: lastMessage,
},
webpush: {
notification: {
title: `${snapValues.authorName}`,
body: lastMessage,
icon: authorPhotoUrl ? authorPhotoUrl : '/apple-touch-icon.png',
image,
click_action: `https://www.react-most-wanted.com/chats/${senderUid}`,
},
},
data: {
test: 'test',
},
}
const tokensSnap = await admin
.database()
.ref(`notification_tokens/${receiverUid}`)
.once('value')
if (tokensSnap.exists()) {
tokensSnap.forEach((t) => {
messages.push({ token: t.key, ...payload })
})
}
await admin.messaging().sendAll(messages)
}
})
Upvotes: 1