Skip to main content
Integrate push notifications into your Flutter app using Firebase Cloud Messaging (FCM) to deliver real-time updates across both Android and iOS platforms with a unified codebase.
Flutter’s cross-platform nature allows you to implement push notifications once and deploy to both platforms, but platform-specific configuration is still required.

Prerequisites

Firebase Project

Active Firebase project with FCM enabled

Platform Setup

Android google-services.json and iOS GoogleService-Info.plist

social.plus SDK

social.plus Flutter SDK properly integrated

Certificates

iOS APNs certificate and Android FCM configuration

Step 1: Install Dependencies

Add the Firebase Messaging plugin to your pubspec.yaml:
dependencies:
  flutter:
    sdk: flutter
  
  # social.plus SDK
  amity_sdk: ^6.x.x
  
  # Firebase dependencies
  firebase_core: ^2.24.2
  firebase_messaging: ^14.7.10
  
  # Optional: For local notifications
  flutter_local_notifications: ^16.3.2
  
  # Optional: For permission handling
  permission_handler: ^11.1.0
Always use the latest stable versions. Check pub.dev for current version numbers.

Step 2: Platform Configuration

Android Configuration

  1. Add google-services.json to android/app/
  2. Update build.gradle files:
// android/build.gradle
buildscript {
  dependencies {
    classpath 'com.google.gms:google-services:4.3.15'
  }
}

// android/app/build.gradle
apply plugin: 'com.google.gms.google-services'

android {
  compileSdkVersion 34
  
  defaultConfig {
    minSdkVersion 21
    targetSdkVersion 34
  }
}
  1. Add permissions to android/app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- Push notification permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    
    <application
        android:label="Your App"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        
        <!-- Your activities -->
        
    </application>
</manifest>

iOS Configuration

  1. Add GoogleService-Info.plist to ios/Runner/
  2. Enable Push Notifications capability in Xcode
  3. Generate APNs certificate following the iOS setup guide
  4. Update Runner-Info.plist for background modes:
<!-- ios/Runner/Info.plist -->
<dict>
    <!-- Existing keys -->
    
    <key>UIBackgroundModes</key>
    <array>
        <string>background-fetch</string>
        <string>remote-notification</string>
    </array>
    
    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>
</dict>
  1. Update AppDelegate.swift:
// ios/Runner/AppDelegate.swift
import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
    }
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Step 3: Upload Certificates to social.plus Console

Android - FCM Service Account

  1. Generate FCM service account JSON:
    • Go to Firebase Console → Project Settings → Service Accounts
    • Click “Generate new private key”
    • Download the JSON file
  2. Upload to social.plus Console:
    • Navigate to Settings → Push Notifications
    • Upload the FCM service account JSON file

iOS - APNs Certificate

  1. Generate .p12 certificate following the iOS setup guide
  2. Upload to social.plus Console:
    • Navigate to Settings → Push Notifications
    • Upload the .p12 file with password

Best Practices

Platform-Specific Handling: While Flutter allows shared code, some platform-specific handling is necessary.
// Handle platform differences
Future<void> handlePlatformSpecificSetup() async {
  if (Platform.isIOS) {
    // iOS-specific handling
    await _handleIOSSpecificSetup();
  } else if (Platform.isAndroid) {
    // Android-specific handling
    await _handleAndroidSpecificSetup();
  }
}
Token State Management: Keep token state consistent across app lifecycle.
class NotificationState extends ChangeNotifier {
  String? _fcmToken;
  bool _isRegistered = false;
  
  String? get fcmToken => _fcmToken;
  bool get isRegistered => _isRegistered;
  
  Future<void> updateToken(String token) async {
    _fcmToken = token;
    await _registerWithSDK(token);
    _isRegistered = true;
    notifyListeners();
  }
}
Robust Error Management: Handle various failure scenarios gracefully.
class PushNotificationErrorHandler {
  static void handleError(dynamic error) {
    if (error is FirebaseException) {
      _handleFirebaseError(error);
    } else if (error is PlatformException) {
      _handlePlatformError(error);
    } else {
      _handleGenericError(error);
    }
  }
  
  static void _handleFirebaseError(FirebaseException error) {
    // Handle Firebase-specific errors
    print('Firebase error: ${error.message}');
  }
}

Troubleshooting

Token Not Generated:
  • Verify Firebase configuration files are correctly placed
  • Check internet connectivity
  • Ensure permissions are granted
iOS Notifications Not Working:
  • Verify APNs certificate is uploaded to social.plus Console
  • Test with TestFlight or App Store build (not debug)
  • Check iOS project capabilities
Android Notifications Not Working:
  • Verify FCM service account JSON is uploaded
  • Check google-services.json placement
  • Ensure minSdkVersion >= 21
iOS Debug Builds:
  • Push notifications don’t work with debug builds
  • Use TestFlight for testing
Android 13+ Permission:
  • Runtime notification permission required
  • Handle permission request properly
// Check Android version and request permission
if (Platform.isAndroid) {
  final androidInfo = await DeviceInfoPlugin().androidInfo;
  if (androidInfo.version.sdkInt >= 33) {
    await Permission.notification.request();
  }
}
Testing Strategy: Always test push notifications on physical devices with production builds, as simulators and debug builds have limitations with push notification delivery.