FCM 通知仅在应用程序打开时传送(iOS Flutter)
FCM notifications delivering only with the app opened (iOS Flutter)
在这个项目中,如果一个给定的用户做了某事,其他用户就会收到来自 Firebase Messaging 的推送。在 android 中,它工作正常,但在 iOS 中,只有打开应用程序,消息才会到达用户手机。如果在后台,当您再次应用该应用时,它会显示通知
我已经做过的事情:
- 1 在 developers.apple 中创建一个密钥并在 firebase
中应用它
- 2 为我的项目提供 googleservices.plist
- 3 打开推送通知和后台模式,并在后台模式下启用后台获取和远程通知。
- 4 在我的 info.plist 中添加了这段代码:
<key>FirebaseScreenReportingEnabled</key>
<true/>
<key>FirebaseAppDelegateProxyEnabled</key>
<true/>
并且在 AppDelegate.swift 中,我已经尝试了这两个代码:
1(来自 FirebaseMessaging 文档)
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
和 2
import UIKit
import Flutter
import Firebase
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
第二个在应用程序打开时收到消息,而第一个根本没有收到。
我正在使用 FlutterLocalNotifications 来处理何时打开应用程序,并且可能 LocalNotifications 和 FCM 之间存在一些冲突(我不确定,只是在想)。
我该如何处理才能接收后台通知?:
有什么想念的吗?以下代码是我的PushNotifications.dart
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:app_md/providers/auth_provider.dart';
import 'package:app_md/providers/notification_plugin.dart';
import 'package:app_md/utils/app_routes.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
}
if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
}
// Or do other work.
}
class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance = PushNotificationsManager
._();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final NotificationPlugin _notificationPlugin = NotificationPlugin();
Future<void> init() async {
if (Platform.isIOS) {
_firebaseMessaging.requestNotificationPermissions(
IosNotificationSettings());
}
_firebaseMessaging.configure(
// Called when the app is in the foreground and we receive a push notif.
onMessage: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
print(message['notification']['body']);
_notificationPlugin.showNotification(
title: 's',
content: message['notification']['body']
);
//sendNotification();
},
// Called when the app has been closed completely and its opened
// from the notification directly
onBackgroundMessage: Platform.isAndroid ? myBackgroundMessageHandler:null,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
// _navigateToItemDetail(message);
},
// Called when the app is in the background and its opened from the notif
onResume: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
},
);
}
subscribeToTopicNotification() async {
await _firebaseMessaging.subscribeToTopic("MYTOPIC");
}
unsubscribeToTopicNotification() async {
await _firebaseMessaging.unsubscribeFromTopic("MYTOPIC");
}
Future sendNotification(String body, String title, bool isAdm) async {
!isAdm ? subscribeToTopicNotification() : null;
final String url = 'https://fcm.googleapis.com/fcm/send';
var data;
data =
'{"notification": {"body": "${body}", "title": "${title}", "content_available": "true"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK"}, "to": "/topics/MYTOPIC"}';
final response = await http.post(
url,
headers: <String, String>{
"Content-Type": "application/json",
"Keep-Alive": "timeout=5",
"Authorization": "MYKEY"
},
body: data
);
print(response.body);
}
}
看来您发送的是数据消息而不是通知消息。您描述的行为(重新打开应用程序时发送通知)是数据消息的行为。 docs.
中的更多信息
在这个项目中,如果一个给定的用户做了某事,其他用户就会收到来自 Firebase Messaging 的推送。在 android 中,它工作正常,但在 iOS 中,只有打开应用程序,消息才会到达用户手机。如果在后台,当您再次应用该应用时,它会显示通知
我已经做过的事情:
- 1 在 developers.apple 中创建一个密钥并在 firebase 中应用它
- 2 为我的项目提供 googleservices.plist
- 3 打开推送通知和后台模式,并在后台模式下启用后台获取和远程通知。
- 4 在我的 info.plist 中添加了这段代码:
<key>FirebaseScreenReportingEnabled</key>
<true/>
<key>FirebaseAppDelegateProxyEnabled</key>
<true/>
并且在 AppDelegate.swift 中,我已经尝试了这两个代码: 1(来自 FirebaseMessaging 文档)
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
和 2
import UIKit
import Flutter
import Firebase
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
第二个在应用程序打开时收到消息,而第一个根本没有收到。 我正在使用 FlutterLocalNotifications 来处理何时打开应用程序,并且可能 LocalNotifications 和 FCM 之间存在一些冲突(我不确定,只是在想)。
我该如何处理才能接收后台通知?:
有什么想念的吗?以下代码是我的PushNotifications.dart
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:app_md/providers/auth_provider.dart';
import 'package:app_md/providers/notification_plugin.dart';
import 'package:app_md/utils/app_routes.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;
Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
}
if (message.containsKey('notification')) {
// Handle notification message
final dynamic notification = message['notification'];
}
// Or do other work.
}
class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance = PushNotificationsManager
._();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
final NotificationPlugin _notificationPlugin = NotificationPlugin();
Future<void> init() async {
if (Platform.isIOS) {
_firebaseMessaging.requestNotificationPermissions(
IosNotificationSettings());
}
_firebaseMessaging.configure(
// Called when the app is in the foreground and we receive a push notif.
onMessage: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
print(message['notification']['body']);
_notificationPlugin.showNotification(
title: 's',
content: message['notification']['body']
);
//sendNotification();
},
// Called when the app has been closed completely and its opened
// from the notification directly
onBackgroundMessage: Platform.isAndroid ? myBackgroundMessageHandler:null,
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
// _navigateToItemDetail(message);
},
// Called when the app is in the background and its opened from the notif
onResume: (Map<String, dynamic> message) async {
print("onMessage: ${message}");
},
);
}
subscribeToTopicNotification() async {
await _firebaseMessaging.subscribeToTopic("MYTOPIC");
}
unsubscribeToTopicNotification() async {
await _firebaseMessaging.unsubscribeFromTopic("MYTOPIC");
}
Future sendNotification(String body, String title, bool isAdm) async {
!isAdm ? subscribeToTopicNotification() : null;
final String url = 'https://fcm.googleapis.com/fcm/send';
var data;
data =
'{"notification": {"body": "${body}", "title": "${title}", "content_available": "true"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK"}, "to": "/topics/MYTOPIC"}';
final response = await http.post(
url,
headers: <String, String>{
"Content-Type": "application/json",
"Keep-Alive": "timeout=5",
"Authorization": "MYKEY"
},
body: data
);
print(response.body);
}
}
看来您发送的是数据消息而不是通知消息。您描述的行为(重新打开应用程序时发送通知)是数据消息的行为。 docs.
中的更多信息