Firebase Cloud Messaging 仅在发布时才起作用
Firebase Cloud Messaging doesn't work only when released
我已经在我的 Flutter 应用程序中实现了 Firebase 云消息传递,并且在大多数情况下它似乎都能正常工作。我可以在我的应用程序中收到通知:
- 使用
flutter run
- 使用
flutter run --release
- 使用 Xcode 的产品 > 运行
全部针对我的 iPhone 链接到计算机。我正在使用口味(开发、质量保证、生产),它适用于所有口味。
当我将它打包用于 Firebase App Distribution 或 Testflight 时,它不起作用。专注于 App Distribution 更容易,所以我将解决我在那里所做的事情。
在设置消息时,我在 XCode 中启用了推送通知(我最初遇到了开发 APNs 的问题,但我更改了配置以使用生产服务)。这是我的权利文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:N/A</string>
</array>
</dict>
</plist>
并且 Info.plist 文件中也启用了背景模式:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
我根据需要在 Apple Developer Portal 中创建了一个密钥:
我已根据需要将其上传到 Firebase:
部署到 App Distribution 时,我 运行 使用以下命令:
flutter build ios --flavor <env>
cd ios
xcodebuild -workspace Runner.xcworkspace -scheme <env> archive -archivePath Runner.xcarchive
xcodebuild -exportArchive -archivePath Runner.xcarchive -exportOptionsPlist exportOptions.plist -exportPath ../build/ios -allowProvisioningUpdates
哪里是我的口味之一,如上所述,我的exportOptions.plist是
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>method</key>
<string>ad-hoc</string>
</dict>
</plist>
我很乐意提供更多线索、配置和解释,但现在,我不知道缺少什么以及可能导致此行为的原因。所以问题是,为什么推送通知在通过存档部署时不起作用?
TLDR:我的 AppDelegate.swift 中缺少 application.registerForRemoteNotifications()
。
看来我的 AppDelegate.swift 会对 post 有所帮助:
@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
}
let controller : FlutterViewController = window.rootViewController as! FlutterViewController
let flavorChannel = FlutterMethodChannel(name: "flavor", binaryMessenger: controller.binaryMessenger)
flavorChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
result(Bundle.main.infoDictionary?["Flavor"])
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
我们已经根据 firebase_messaging 项目中的 README 实施了说明(https://pub.dev/packages/firebase_messaging). This necessitated adding if #available
lines. Yes, this is only for doing method swizzling, and we weren't (i.e. we didn't have FirebaseAppDelegateProxyEnabled
in our Info.plist file), but I stumbled upon Flutter FCM on iOS 14(他们正在实施 swizzling),并注意到他们的文件中多了一行:application.registerForRemoteNotifications()
。一旦我添加了该行(在 return 之前的行),推送通知就开始工作了。
我已经在我的 Flutter 应用程序中实现了 Firebase 云消息传递,并且在大多数情况下它似乎都能正常工作。我可以在我的应用程序中收到通知:
- 使用
flutter run
- 使用
flutter run --release
- 使用 Xcode 的产品 > 运行
全部针对我的 iPhone 链接到计算机。我正在使用口味(开发、质量保证、生产),它适用于所有口味。
当我将它打包用于 Firebase App Distribution 或 Testflight 时,它不起作用。专注于 App Distribution 更容易,所以我将解决我在那里所做的事情。
在设置消息时,我在 XCode 中启用了推送通知(我最初遇到了开发 APNs 的问题,但我更改了配置以使用生产服务)。这是我的权利文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>production</string>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:N/A</string>
</array>
</dict>
</plist>
并且 Info.plist 文件中也启用了背景模式:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
我根据需要在 Apple Developer Portal 中创建了一个密钥:
我已根据需要将其上传到 Firebase:
部署到 App Distribution 时,我 运行 使用以下命令:
flutter build ios --flavor <env>
cd ios
xcodebuild -workspace Runner.xcworkspace -scheme <env> archive -archivePath Runner.xcarchive
xcodebuild -exportArchive -archivePath Runner.xcarchive -exportOptionsPlist exportOptions.plist -exportPath ../build/ios -allowProvisioningUpdates
哪里是我的口味之一,如上所述,我的exportOptions.plist是
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>method</key>
<string>ad-hoc</string>
</dict>
</plist>
我很乐意提供更多线索、配置和解释,但现在,我不知道缺少什么以及可能导致此行为的原因。所以问题是,为什么推送通知在通过存档部署时不起作用?
TLDR:我的 AppDelegate.swift 中缺少 application.registerForRemoteNotifications()
。
看来我的 AppDelegate.swift 会对 post 有所帮助:
@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
}
let controller : FlutterViewController = window.rootViewController as! FlutterViewController
let flavorChannel = FlutterMethodChannel(name: "flavor", binaryMessenger: controller.binaryMessenger)
flavorChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
result(Bundle.main.infoDictionary?["Flavor"])
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
我们已经根据 firebase_messaging 项目中的 README 实施了说明(https://pub.dev/packages/firebase_messaging). This necessitated adding if #available
lines. Yes, this is only for doing method swizzling, and we weren't (i.e. we didn't have FirebaseAppDelegateProxyEnabled
in our Info.plist file), but I stumbled upon Flutter FCM on iOS 14(他们正在实施 swizzling),并注意到他们的文件中多了一行:application.registerForRemoteNotifications()
。一旦我添加了该行(在 return 之前的行),推送通知就开始工作了。