Flutter FCM Part 2: Subscribing to Topics, Broadcasting Notifications, and Navigating to Screens

Amanullah Bahram
3 min readNov 11, 2024

--

In this part, we’ll expand our Firebase Cloud Messaging (FCM) setup to demonstrate the following functionalities:
1. Subscribing Devices to a Topic
2. Broadcasting Notifications to All Devices
3. Handling Navigation to a Screen on Notification Click

We’ll also include scripts for generating FCM tokens and sending notifications via Firebase Admin SDK to enable server-side integration.

1. Subscribing to a Topic

The updated NotificationService class already includes a method to subscribe to a topic:

Future<void> subscribeToTopic(String topic) async {
await FirebaseMessaging.instance.subscribeToTopic(topic);
print("Subscribed to $topic");
}

In the initialize method, devices are subscribed to the all_devices topic:

await subscribeToTopic('all_devices');

This ensures that all devices automatically subscribe to the `all_devices` topic upon initialization.

2. Broadcasting Notifications to All Devices

To broadcast notifications, you need to:
- Generate an OAuth2 token.
- Send the notification via the Firebase Admin SDK.

Generating OAuth2 Token

The following script uses google-auth-library to generate an OAuth2 token.
Save the following script in a file, e.g., generateToken.js:

const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth({
keyFile: './serviceaccount.json', // Path to your downloaded JSON key file
scopes: 'https://www.googleapis.com/auth/firebase.messaging'
});

async function getAccessToken() {
const client = await auth.getClient();
const accessToken = await client.getAccessToken();
return accessToken.token;
}

getAccessToken().then(token => {
console.log('Generated OAuth2 token:', token);
// Use this token for your Firebase request
}).catch(error => {
console.error('Error generating token:', error);
});

Dependencies:
Run the following command to install dependencies:

npm install google-auth-library

Sending Notifications to the Topic

Once you have the token, use the following script to send notifications to the all_devices topic. Save it in a file, e.g., sendNotification.js:

// npm install axios
const axios = require('axios');

const token = 'YOUR_GENERATED_TOKEN'; // Replace with your generated token

const url = 'https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send';

const messagePayload = {
message: {
topic: "all_devices",
notification: {
title: "Broadcast Notification",
body: "This message is sent to all devices!"
},
data: {
type: "chat" // Used for navigation
},
android: {
priority: "high",
notification: {
channel_id: "high_importance_channel"
}
}
}
};

const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};

axios.post(url, messagePayload, { headers })
.then(response => {
console.log('Message sent successfully:', response.data);
})
.catch(error => {
console.error('Error sending message:', error.response ? error.response.data : error.message);
});

Replace `YOUR_PROJECT_ID` with your Firebase project ID.

3. Handling Navigation on Notification Click

The NotificationService class handles navigation to a specific screen (`ChatScreen`) when a notification is clicked:

Notification Payload
In the messagePayload, include a data field to specify the type of notification:

"data": {
"type": "chat"
}

Handling the Data
The NotificationService processes the type field in the _handleBackgroundMessage method:

void _handleBackgroundMessage(String message) {
if (message == 'chat') {
navigatorKey.currentState?.push(MaterialPageRoute(
builder: (context) => ChatScreen(),
));
}
}

4. Testing the Implementation

Steps to Test:
1. Run the Flutter App: Ensure that NotificationService.initialize() is called in the main method.
2. Subscribe to the Topic: All devices will automatically subscribe to the all_devices topic.
3. Send Notifications: Use the sendNotification.js script to broadcast notifications.
4. Verify Navigation: On receiving the notification, tapping it should navigate to the ChatScreen.

5. Updated Code Highlights

Main Entry (`main.dart`)

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await NotificationService.instance.initialize();

runApp(MyApp());
}

Notification Service Updates
- Foreground Notification: Shows notifications immediately.
- Background Notification: Navigates to ChatScreen based on the type field.

Conclusion

This guide demonstrates how to:
1. Subscribe devices to an FCM topic.
2. Broadcast notifications to all devices.
3. Handle custom data for navigation in Flutter.

With the server-side scripts, you can seamlessly integrate backend services to manage notifications for your app.

--

--

Amanullah Bahram
Amanullah Bahram

No responses yet