Flutter语言 - Firebase_messaging从v7迁移到v11 -未调用onMessage



我需要一些帮助来迁移我的项目。基本上这个项目现在有点老了,已经运行了将近3年,直到现在它还是用flutter 1.22.6建造的。现在我正试图将其迁移到v2.10.3,迁移几乎完成了。最后一个不工作的部分是iOS推送通知。

旧版本在firebase_messaging v.7.0.3上运行,它工作得很好。升级颤振需要9.0.0或更高版本。

我已经做了基本的代码迁移和Android是OK的,但在iOS上我的onMessage处理程序从来没有被调用。当应用程序在后台时,推送正在传递,通知正在正确显示。但是当它在前台时,或者我点击那个通知,应用程序进入前台,但是回调没有被触发。

我在日志中看到的唯一错误是:nw_endpoint_handler_set_adaptive_read_handler [C6.1 216.58.212.42:443 ready channel-flow (satisfied (Path is satisfied), viable, interface: en0, ipv4, dns)] unregister notification for read_timeout failed

OFC我已经看过了堆栈和其他地方的大多数主题,但这些解决方案都不适合我。我没有使用任何其他插件,如flutter_local_notifications或类似的,这可能会导致错误。

最重要的代码:

颤振医生

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel unknown, 2.10.3, on macOS 11.6 20G165 darwin-x64, locale
pl-PL)
[✓] Android toolchain - develop for Android devices (Android SDK version
33.0.0-rc3)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.67.1)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

pubspec.yaml

firebase_core: 1.16.0
firebase_messaging: 11.3.0
google_ml_kit: 0.7.3

AppDelegate.swift

override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
disableCache();
FirebaseConfiguration.shared.setLoggerLevel(.min)
FirebaseApp.configure()
self.SetupPushNotification(application: application)

func SetupPushNotification(application: UIApplication) -> () {
if #available(iOS 10, *){ UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge])
{(granted,error) in
if granted{
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
} else {
print("User Notification permission denied: (error?.localizedDescription ?? "error")")
}
}
}
}

override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
NotificationDeviceToken.sharedInstance.setToken(token: tokenString(deviceToken))
}
override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications: (error.localizedDescription)")
}

override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
print(userInfo)
}
func tokenString(_ deviceToken:Data) -> String{
let bytes = [UInt8](deviceToken)
var token = ""
for byte in bytes{
token += String(format: "%02x",byte)
}
return token 
}

main.dart

void startApp(AppConfig config) async {
// add this, and it should be the first line in main method
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
...
}

app.dart

void init(BuildContext context, AppCubit cubit,
SubscriptionManager subscriptionManager) {
await FirebaseMessaging.instance.getToken();
FirebaseMessaging.onMessage.listen((map) {
_log.debug('onMessage: ${map.data}');
final push = Push(map.data, PushType.onMessage);
_streamController.add(push);
return Future<bool>.value(true);
});
FirebaseMessaging.onMessageOpenedApp.listen((map) {
_log.debug('onMessageOpenedApp: ${map.data}');
_startAppFromPush = true;
final push = Push(map.data, PushType.onLaunch);
_streamController.add(push);
return Future<bool>.value(true);
});
}

Info.plist

...
<key>FirebaseAppDelegateProxyEnabled<key/>
<false/>
...

任何帮助将不胜感激。提前谢谢。

看来我找到解决办法了。

我在github flutterfire项目中发现了一个问题。其中一个话题和我的麻烦非常相似。https://github.com/firebase/flutterfire/issues/4300

问题是,从FCM发送的每个推送都在有效载荷中获得额外的字段,称为gcm.message_id。来自APNS的通知没有得到这个字段。

插件firebase_messaging从版本9开始到现在正在验证这个字段,如果push不包含它,则不会触发回调onMessageonMessageOpenedApp

如果你遇到类似的麻烦,你有两个选择:

  • 在您的APNS消息有效载荷中添加缺失字段
  • 使用firebase_messaging插件创建自己的fork,并在2个地方修改FLTFirebaseMessagingPlugin,其中适当的if语句位于

我希望这将对你们中的一些人有用。我花了很多时间研究这个问题。

最新更新