Masamune logo

Masamune Notification Firebase

Follow on GitHub Follow on X Follow on YouTube Maintained with Melos

GitHub Sponsor


[GitHub](https://github.com/mathrunet) | [YouTube](https://www.youtube.com/c/mathrunetchannel) | [Packages](https://pub.flutter-io.cn/publishers/mathru.net/packages) | [X](https://x.com/mathru) | [LinkedIn](https://www.linkedin.com/in/mathrunet/) | [mathru.net](https://mathru.net)


Masamune Notification Firebase

Overview

masamune_notification_firebase provides Firebase Cloud Messaging (FCM) integration for Masamune apps. Send and receive push notifications through Firebase.

Note: Requires masamune_notification for core notification functionality.

Usage

Installation

flutter pub add masamune_notification
flutter pub add masamune_notification_firebase

Register the Adapter

Configure FirebaseRemoteNotificationMasamuneAdapter for push notifications.

// lib/adapter.dart

import 'package:masamune_notification_firebase/masamune_notification_firebase.dart';
import 'package:katana_functions_firebase/katana_functions_firebase.dart';

final functionsAdapter = FirebaseFunctionsAdapter(
  options: DefaultFirebaseOptions.currentPlatform,
  region: FirebaseRegion.asiaNortheast1,
);

/// Masamune adapters used in the application.
final masamuneAdapters = <MasamuneAdapter>[
  const UniversalMasamuneAdapter(),

  FirebaseRemoteNotificationMasamuneAdapter(
    options: DefaultFirebaseOptions.currentPlatform,  // Firebase config
    functionsAdapter: functionsAdapter,                // For sending via backend
    loggerAdapters: [FirebaseLoggerAdapter()],        // Optional analytics
    androidChannelId: "default_channel",              // Android notification channel
    androidChannelName: "General Notifications",
  ),
];

Initialize Firebase Messaging

Initialize the remote notification controller to handle push notifications:

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final remoteNotification = appRef.controller(RemoteNotification.query());

    // Initialize on app start
    remoteNotification.initialize(
      onBackgroundMessage: _backgroundMessageHandler,
      onForegroundMessage: (message) {
        print("Foreground: ${message.notification?.title}");
        // Show dialog, update UI, etc.
      },
      onMessageOpenedApp: (message) {
        print("Opened from notification: ${message.data}");
        // Navigate to specific page
      },
    );

    return MasamuneApp(...);
  }
}

// Top-level function for background messages
@pragma('vm:entry-point')
Future<void> _backgroundMessageHandler(RemoteMessage message) async {
  print("Background: ${message.notification?.title}");
}

Request Permissions

Request notification permissions on iOS and Android 13+:

class PermissionPage extends PageScopedWidget {
  @override
  Widget build(BuildContext context, PageRef ref) {
    final notification = ref.app.controller(RemoteNotification.query());

    return ElevatedButton(
      onPressed: () async {
        final granted = await notification.requestPermission(
          alert: true,
          badge: true,
          sound: true,
        );
        
        if (granted) {
          print("Notification permission granted");
        }
      },
      child: const Text("Enable Notifications"),
    );
  }
}

Get FCM Token

Retrieve the device's FCM token for backend registration:

final remoteNotification = ref.app.controller(RemoteNotification.query());

final token = await remoteNotification.getToken();
print("FCM token: $token");

// Send token to your backend
await saveTokenToBackend(token);

// Listen for token refresh
remoteNotification.onTokenRefresh.listen((newToken) {
  print("Token refreshed: $newToken");
  saveTokenToBackend(newToken);
});

Subscribe to Topics

Subscribe to topics for group notifications:

// Subscribe
await remoteNotification.subscribeTopic("news");
await remoteNotification.subscribeTopic("promotions");

// Unsubscribe
await remoteNotification.unsubscribeTopic("promotions");

Send Notifications from Backend

Use SendRemoteNotificationFunctionsAction:

final functions = ref.app.functions();

await functions.execute(
  SendRemoteNotificationFunctionsAction(
    title: "New Message",
    body: "You have a new message from John",
    token: recipientToken,  // Specific user
    // Or: topic: "news",  // All subscribed users
    data: {
      "type": "chat",
      "senderId": "user_123",
    },
  ),
);

Backend Implementation:

// Cloud Functions
export const sendNotification = functions.https.onCall(async (data, context) => {
  const message = {
    notification: {
      title: data.title,
      body: data.body,
    },
    data: data.data,
    token: data.token,  // or topic: data.topic
  };

  await admin.messaging().send(message);
  return { success: true };
});

Handle Notification Taps

Navigate users when they tap notifications:

remoteNotification.initialize(
  onMessageOpenedApp: (message) {
    final data = message.data;
    
    if (data['type'] == 'chat') {
      context.router.push(ChatPage.query(userId: data['senderId']));
    }
  },
);

Tips

  • Configure Android notification channels in the adapter
  • Handle background messages with top-level @pragma('vm:entry-point') functions
  • Store FCM tokens in your database for targeted notifications
  • Use topics for broadcast notifications
  • Test on real devices (FCM doesn't work in simulators)

GitHub Sponsors

Sponsors are always welcome. Thank you for your support!

https://github.com/sponsors/mathrunet

Libraries

masamune_notification_firebase
Package for receiving PUSH notifications using Firebase Messaging. Firebase Functions can also be used to send notifications.