Flutter Firebase Chat App – Part 3: Push Notifications for New Messages
Learn how to implement push notifications for new chat messages in Flutter using Firebase Cloud Messaging and Cloud Functions. Complete production-ready setup guide.
Introduction
In the previous article, we implemented real-time messaging using Firestore streams. Messages appear instantly when both users have the chat screen open.
However, if the receiver is not inside the chat screen or the app is closed, we need push notifications to alert them.
In this article we will implement:
- FCM token storage
- Cloud Function trigger for new messages
- Sending push notifications
- Handling notification clicks in Flutter
Chat Notification Architecture
User A sends message
↓
Firestore message document created
↓
Cloud Function trigger
↓
Fetch receiver FCM token
↓
Send push notification
↓
User B receives notification
Step 1: Add Firebase Messaging Package
dependencies: firebase_messaging: latest_version
Request Notification Permission
FirebaseMessaging messaging = FirebaseMessaging.instance; await messaging.requestPermission( alert: true, badge: true, sound: true, );
Step 2: Get FCM Token
String? token = await FirebaseMessaging.instance.getToken();
print("FCM Token: $token");
Store this token in the user document.
await FirebaseFirestore.instance
.collection("users")
.doc(userId)
.update({
"fcmToken": token
});
Step 3: Cloud Function Trigger
exports.sendMessageNotification =
functions.firestore
.document('conversations/{conversationId}/messages/{messageId}')
.onCreate(async (snapshot, context) => {
const message = snapshot.data();
const receiverId = message.receiverId;
const userDoc = await admin
.firestore()
.collection('users')
.doc(receiverId)
.get();
const token = userDoc.data().fcmToken;
await admin.messaging().send({
token: token,
notification: {
title: "New Message",
body: message.text
}
});
});
Deploy Function
firebase deploy --only functions
Handle Foreground Notifications
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print("New message received");
});
Handle Notification Click
FirebaseMessaging.onMessageOpenedApp.listen(
(RemoteMessage message) {
String conversationId =
message.data['conversationId'];
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ChatScreen(conversationId),
),
);
},
);
Send Data Payload with Notification
await admin.messaging().send({
token: token,
notification: {
title: "New Message",
body: message.text
},
data: {
conversationId: context.params.conversationId
}
});
Prevent Notification Spam
- Do not notify sender
- Check if receiver is already inside chat
Production Optimization
- Batch notifications if many users
- Use topics for group chats
- Handle token refresh
Token Refresh Listener
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) {
print("Updated token: $newToken");
});
Security Best Practices
- Never expose server keys
- Send notifications only via backend
- Validate user permissions
Testing Notifications
- Send test notification from Firebase Console
- Check Cloud Function logs
Production Flow Summary
Message sent
↓
Firestore write
↓
Cloud Function trigger
↓
Fetch receiver FCM token
↓
Send notification
↓
User opens chat from notification
Conclusion
Push notifications are essential for real-time communication apps. By combining Firestore triggers with Firebase Cloud Messaging, we can deliver instant alerts when new messages arrive.
In Part 4, we will implement: Chat Conversation List Screen (Recent Chats + Unread Count).
Share
What's Your Reaction?
Like
0
Dislike
0
Love
0
Funny
0
Angry
0
Sad
0
Wow
0