【发布时间】:2021-11-02 10:02:46
【问题描述】:
我正在进行的一个项目需要使用 FCM 推送通知和消息来进行 VoIP 控制等。
问题:
我的 iOS 物理设备接收推送通知,但仅在应用程序处于后台或关闭时不在前台时。此外,它不会收到任何 fcm 消息(数据)通知,例如只有数据而没有通知标题/正文的消息,即 VoIP 状态消息。
我的设置步骤如下(详细设置和我遵循的一般流程可以在here找到):
-
注册 (
Info.plist)(见here) -
下载并使用 Xcode 安装
GoogleService-Info.plist(参见 here) -
创建 APNS 密钥并启用推送通知并将
.p8文件上传到 Firebase(见here) -
修改用Swift代码:
AppDelegate.swift代码:
import UIKit
import Flutter
import Firebase // this is added, and (see further down)
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure() //add this before the code below
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
- 添加 功能到 iOS
Info.plist 文件功能(后台获取、通知等)
<?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>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
</array>
...
<key>NSCameraUsageDescription</key>
<string>Allows taking a self-portrait profile image or sending a photo while chating</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Allows using your location to make determining country & location picking easier (optional)</string>
<key>NSMicrophoneUsageDescription</key>
<string>Allows using micrphone to chat with someone when making a call</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Allows opening files from gallery</string>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>bluetooth-central</string>
<string>external-accessory</string>
<string>fetch</string>
<string>location</string>
<string>processing</string>
<string>remote-notification</string>
<string>voip</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
注意:无法启用here 所示的背景模式,而是使用一组复选框启用它们以启用Background Fetch 等。
- FCM - 收听和显示以及使用某些通知(显示)服务(例如awesome notifications)的通知/消息
实现遵循这些guidelines:
前台消息:
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
...
});
背景信息:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
问题扩展:
在调试时,如果 iOS 应用程序处于前台/后台,并且向设备发送了测试通知或有效的 VoIP 呼叫(FCM 数据消息),则该应用程序永远不会收到或(也不会命中所需的断点)。
什么会导致应用/iOS 收不到这些 FCM 消息?
从 Firebase 云功能服务发送的示例 VoIP 消息:
// build notification on liked status
const payload = {
token: fcmToken,
data: {
uid: context.auth.uid,
room_id: roomId,
...
},
android: {
priority: 'high',
ttl: 0,
notification: {
priority: 'max',
defaultSound: true,
defaultVibrateTimings: true,
sticky: true,
clickAction: "FLUTTER_NOTIFICATION_CLICK",
}
},
notification: {
title: `Incoming call from ${name}`,
body: `Accept/Reject call`,
// icon: 'your-icon-url', // Add profile image URL here if necessary
// clickAction: 'FLUTTER_NOTIFICATION_CLICK' // required only for onResume or onLaunch callbacks
},
apns: {
payload: {
aps: {
category: "NEW_MESSAGE_CATEGORY",
contentAvailable: true,
}
}
},
headers: {
"apns-push-type": "background",
"apns-priority": "5", // Must be `5` when `contentAvailable` is set to true.
"apns-topic": "io.flutter.plugins.firebase.messaging", // bundle identifier
},
};
await admin.messaging().send(payload);
【问题讨论】:
-
我又看了你的3个问题,更新了我的答案。
标签: android ios swift firebase firebase-cloud-messaging