繁体   English   中英

Firebase 在检索发件人 ID 的 FCM 令牌之前未设置 APNS 设备令牌 - Flutter iOS

[英]Firebase APNS device token not set before retrieving FCM Token for Sender ID - Flutter iOS

使用颤振+firebase 在 iOS 中未收到通知

在控制台中低于警告 -

[FlutterVoipPushNotificationPlugin] voipRegistration

8.10.0 - [Firebase/Messaging][I-FCM002022] 在检索发件人 ID“445223936748”的 FCM 令牌之前未设置 APNS 设备令牌。 此 FCM 令牌的通知将不会通过 APNS 传递。请确保在设置 APNS 设备令牌后重新检索 FCM 令牌。

[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials credentials.token = {length = 32, bytes = 0xc42015a5 2ba37137 7af02cb4 e389522d... d93f5c94 6ce6f0b4 }, type = PKPushTypeVoIP

[FlutterVoipPushNotificationPlugin] handleRemoteNotificationsRegistered notification.userInfo = { deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4; }

[FlutterVoipPushNotificationPlugin] didUpdatePushCredentials credentials.token = {length = 32, bytes = 0xc42015a5 2ba37137 7af02cb4 e389522d... d93f5c94 6ce6f0b4 }, type = PKPushTypeVoIP

[FlutterVoipPushNotificationPlugin] handleRemoteNotificationsRegistered notification.userInfo = { deviceToken = c42015a52ba371377af02cb4e389522d8104a7a603d15418d93f5c946ce6f0b4; }

在 firebase 控制台 AppDelegate 文件中添加了.p8 和.p12(生产 APNs 证书) -

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() 得到的令牌; 无效。 Postman的PFA

在此处输入图像描述

Xcode 的 PFA - 在此处输入图像描述

在 android 中收到通知,但在 iOS 中没有收到通知。 如何在 flutter 中获取正确的设备令牌以获取推送通知。

提前致谢。!!!

为什么 fcm 需要 APNToken?

在这里您可以从 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 管理面板发送推送通知并检查已发送通知的队列。 如果您的推送通知存在,请单击sent的链接检查报告(您将同时有两行)。 您可以在那里下载详细的 JSON 和报告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM