提问人:Subhangi Pawar 提问时间:1/18/2022 最后编辑:Subhangi Pawar 更新时间:4/21/2023 访问量:13162
在检索发件人 ID 的 FCM 令牌之前未设置 Firebase APNS 设备令牌 - Flutter iOS
Firebase APNS device token not set before retrieving FCM Token for Sender ID - Flutter iOS
问:
在 iOS 中使用 flutter+firebase 时没有收到通知 使用 connectycube_sdk 2.0.9 进行通话和聊天功能。
在控制台中,警告如下 -
[FlutterVoipPushNotificationPlugin] voip注册
8.10.0 - [Firebase/Messaging][I-FCM002022] 在检索发件人 ID 为“445223936748”的 FCM 令牌之前未设置 APNS 设备令牌。 此 FCM 令牌的通知不会通过 APNS.Be 发送 确保在设置 APNS 设备令牌后重新检索 FCM 令牌。
[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials credentials.token = {长度 = 32,字节 = 0xc42015a5 2ba37137 7af02cb4 E389522D ...d93f5c94 6ce6f0b4 },类型 = PKPushTypeVoIP
[FlutterVoipPushNotification插件] handleRemoteNotificationsRegistered notification.userInfo = { deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4;}
[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials credentials.token = {长度 = 32,字节 = 0xc42015a5 2ba37137 7af02cb4 E389522D ...d93f5c94 6ce6f0b4 },类型 = PKPushTypeVoIP
[FlutterVoipPushNotification插件] handleRemoteNotificationsRegistered notification.userInfo = { deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4;}
在 firebase 控制台中添加了 .p8 和 .p12(生产 APNs 证书) AppDelegate 文件 -
import UIKit
import Flutter
import Firebase
import PushKit
import CallKit
import flutter_voip_push_notification
import flutter_call_kit
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
self.voipRegistration()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
application.registerForRemoteNotifications()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
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()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// Handle incoming pushes
public func pushRegistry(_ registry: PKPushRegistry,
didReceiveIncomingPushWith payload: PKPushPayload,
for type: PKPushType,
completion: @escaping () -> Swift.Void){
print("didReceiveIncomingPushWith")
FlutterVoipPushNotificationPlugin.didReceiveIncomingPush(with: payload, forType: type.rawValue)
let signalType = payload.dictionaryPayload["signal_type"] as! String
if(signalType == "endCall" || signalType == "rejectCall"){
return
}
let uuid = payload.dictionaryPayload["session_id"] as! String
let uID = payload.dictionaryPayload["caller_id"] as! Int
let callerName = payload.dictionaryPayload["caller_name"] as! String
let isVideo = payload.dictionaryPayload["call_type"] as! Int == 1;
FlutterCallKitPlugin.reportNewIncomingCall(
uuid,
handle: String(uID),
handleType: "generic",
hasVideo: isVideo,
localizedCallerName: callerName,
fromPushKit: true
)
completion()
}
// Handle updated push credentials
public func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
// Process the received pushCredentials
FlutterVoipPushNotificationPlugin.didUpdate(pushCredentials, forType: type.rawValue);
}
// Register for VoIP notifications
func voipRegistration(){
// Create a push registry object
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: DispatchQueue.main)
// Set the registry's delegate to self
voipRegistry.delegate = self
// Set the push type to VoIP
voipRegistry.desiredPushTypes = [PKPushType.voIP]
}
}
在 main_dev.dart 文件中
Future<void> main() async {
PrintLog.printLog("ROOT WIDGET ");
await runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
await Firebase.initializeApp();
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
PushNotificationsManager.instance.init();
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
NavigatorKey.notifyLaunch = await NavigatorKey.flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
await SharedPref.getInstance();
HttpOverrides.global = MyHttpOverrides();
FlavorConfig(
variables: {
"env": "dev",
"baseUrl": "https://humanquestapi.demo.brainvire.dev/api/",
"version": "v1/",
},
);
Bloc.observer = HomeBlocObserver();
runApp(const MyApp());
}, (error, stackTrace) {
FirebaseCrashlytics.instance.recordError(error, stackTrace);
});
}
在 PushNotificationManager.dart 文件中
class PushNotificationsManager {
static const TAG = "PushNotificationsManager";
static final PushNotificationsManager _instance =
PushNotificationsManager._internal();
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
PushNotificationsManager._internal() {
Firebase.initializeApp();
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
}
final FlutterVoipPushNotification _voipPush = FlutterVoipPushNotification();
BuildContext? applicationContext;
static PushNotificationsManager get instance => _instance;
Future<dynamic> Function(String? payload)? onNotificationClicked;
init() async {
FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
await firebaseMessaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('ic_launcher_foreground');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: true,
requestBadgePermission: true,
requestAlertPermission: true,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
final InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
String? token;
if (Platform.isAndroid) {
firebaseMessaging.getToken().then((token) {
log('[getToken] token: $token', TAG);
subscribe(token);
}).catchError((onError) {
log('[getToken] onError: $onError', TAG);
});
} else if (Platform.isIOS) {
token = await firebaseMessaging.getAPNSToken();
log(
'[getToken] token: $token',
);
_initIosVoIP();
}
if (!isEmpty(token)) {
subscribe(token);
}
firebaseMessaging.onTokenRefresh.listen((newToken) {
subscribe(newToken);
});
FirebaseMessaging.onMessage.listen((remoteMessage) {
PrintLog.printLog('[onMessage] message: $remoteMessage');
// showNotification(remoteMessage);
if (remoteMessage.data.isNotEmpty &&
remoteMessage.data[PARAM_SIGNAL_TYPE] != null &&
remoteMessage.data[PARAM_CALL_TYPE] != null) {
processCallNotification(remoteMessage.data);
} else if (remoteMessage.data.isNotEmpty &&
remoteMessage.data["message"] != null) {
showNotification(remoteMessage);
} else {
remoteMessage.data.putIfAbsent("message", () => "Notification");
showNotification(remoteMessage);
}
});
FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
FirebaseMessaging.onMessageOpenedApp.listen((remoteMessage) {
PrintLog.printLog('[onMessageOpenedApp] remoteMessage: $remoteMessage');
if (onNotificationClicked != null) {
onNotificationClicked!.call(jsonEncode(remoteMessage.data));
}
});
}
_initIosVoIP() async {
await _voipPush.requestNotificationPermissions();
_voipPush.configure(onMessage: onMessage, onResume: onResume);
_voipPush.onTokenRefresh.listen((token) {
log('[onTokenRefresh] VoIP token: $token', TAG);
subscribe(token);
});
_voipPush.getToken().then((token) {
log('[getToken] VoIP token: $token', TAG);
if (token != null) {
subscribe(token);
}
});
}
Future<dynamic> onDidReceiveLocalNotification(
int id, String? title, String? body, String? payload) {
log('[onDidReceiveLocalNotification] id: $id , title: $title, body: $body, payload: $payload',
PushNotificationsManager.TAG);
return Future.value();
}
Future<dynamic> onSelectNotification(String? payload) {
log('[onSelectNotification] payload: $payload',
PushNotificationsManager.TAG);
if (onNotificationClicked != null) {
onNotificationClicked!.call(payload);
}
return Future.value();
}
}
我们从 await firebaseMessaging.getAPNSToken() 获取的令牌;无效。邮递员的 PFA
在android中收到通知,但在iOS中未收到通知。如何在 flutter 中获取适当的设备令牌以获取推送通知。
提前致谢!!
答:
为什么需要 APNToken for fcm?
在这里,您可以从 FCM 获取令牌,您将收到推送。
FirebaseMessaging.getToken().then((token) async {
print('Token: $token');
}).catchError((e) {
print(e);
});
FirebaseMessaging.onTokenRefresh.listen((newToken) async {
// Save newToken
print('Token: $newToken');
});
你可以尝试使用此令牌,希望这对你有所帮助。对于iOS,请签入真实设备。
Connectycube 推送通知功能通过 APNS 而不是 FCM 工作。预计您无法向 APNS 接收器发送 FCM 推送通知。
首先,检查您的用户是否在Connectycube管理面板中订阅了?然后尝试从 Connectycube 管理面板发送推送通知并检查已发送通知的队列。如果您的推送通知存在,请单击链接检查报告(您将同时有两行)。您可以在其中下载包含报告的详细 JSON。sent
评论