首页 > 解决方案 > 应用程序终止时未收到后台 FCM 通知

问题描述

我正在尝试创建一个系统,其中一个应用程序上的活动通知另一个应用程序上的其他用户。

在这两个应用程序中,通知配置都是这样初始化的,

class PushNotificationService {
  final FirebaseMessaging _fcm = FirebaseMessaging.instance;
  final UserService _userService = locator<UserService>();
  final FirestoreService _firestoreService = locator<FirestoreService>();
  final EventService _eventService = locator<EventService>();
  final AndroidNotificationChannel _channel = AndroidNotificationChannel(
    "high_importance_channel",
    "High Importance Channel",
    "Should be used foreground and background notification",
    importance: Importance.max,
  );

  late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

  Future<void> init() async {
    flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

    await flutterLocalNotificationsPlugin.initialize(
      InitializationSettings(
        android: AndroidInitializationSettings("mipmap/ic_launcher"),
      ),
    );

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(_channel);

    final token = await _fcm.getToken();
    _storeToken(token!);

    FirebaseMessaging.onMessage.listen(_messageHandler);
    FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler);
  }

  Future<void> sendNotificationToListener({
    required String userId,
    required String title,
    required String body,
    Map? data,
  }) async {
    final user = await _firestoreService.readDoc(userId);
    final token = user.data()!['fcmToken'];

    final notification = {
      "title": title,
      "body": body,
    };

    try {
      final body = _constructFCMPayload(token, data ?? {}, notification);
      final response = await http.post(
        Uri.parse('https://fcm.googleapis.com/fcm/send'),
        headers: <String, String>{
          'Content-Type': 'application/json; charset=UTF-8',
          "Authorization":
              "key=<server_key>",
        },
        body: body,
      );
      print("Notification Sent. \nResponse : ${response.body}");
    } catch (e) {
      print("Push Notificaion Error: $e");
    }
  }

  String _constructFCMPayload(String token, Map data, Map notification) {
    return jsonEncode({
      "to": token,
      "data": data,
      "notification": notification,
      "direct_boot_ok": true,
      "priority": "high",
    });
  }

  Future<void> _messageHandler(RemoteMessage message) async {
    final RemoteNotification? notification = message.notification;
    if (notification != null) {
      flutterLocalNotificationsPlugin.show(
        notification.hashCode,
        notification.title,
        notification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            _channel.id,
            _channel.name,
            _channel.description,
            icon: "mipmap/ic_launcher",
          ),
        ),
      );
    }
  }

  Future<void> _storeToken(String token) async {
    final currentUser = _userService.user!;
    _userService.updateUser(currentUser.copyWith(fcmToken: token));
  }
}

Future<void> _backgroundMessageHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  AndroidNotificationChannel _channel = AndroidNotificationChannel(
    "high_importance_channel",
    "High Importance Channel",
    "Should be used foreground and background notification",
    importance: Importance.max,
  );

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  final result = await flutterLocalNotificationsPlugin.initialize(
    InitializationSettings(
      android: AndroidInitializationSettings("mipmap/ic_launcher"),
    ),
  );

  print("onBackgroundMessage: Initialized Notification : $result");

  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(_channel);

  final RemoteNotification? notification = message.notification;

  if (notification != null) {
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          _channel.id,
          _channel.name,
          _channel.description,
          icon: "mipmap/ic_launcher",
        ),
      ),
    );
  }
}

AndroidManifest.xml我也添加了这些数据

<meta-data
      android:name="com.google.firebase.messaging.default_notification_channel_id"
                android:value="high_importance_channel" 
              />

init方法在主屏幕启动时调用。应用程序在前台或后台时收到通知。但不是处于终止模式。请帮忙。

标签: androidflutterfirebase-cloud-messaging

解决方案


推荐阅读