Flutter Pu sh Уведомления: невозможно получать уведомления в фоновом режиме или при закрытии приложения - PullRequest
7 голосов
/ 03 августа 2020

Я разрабатываю приложение для флаттера как для Android, так и для iOS. У него есть уведомления, поэтому я реализовал API firebase_messaging . Я отправляю уведомления на определенные устройства по идентификатору устройства, а также отправляю уведомления на topics.

Я тестирую отправку уведомлений topics, которая на 100% работает в Android. Я следовал руководству по приведенной выше ссылке, а также реализовал настройки iOS. Но в iOS, когда уведомление отправлено, приложение получает его только в том случае, если оно находится на переднем плане. То есть только через onMessage. Если приложение работает в фоновом режиме или закрыто, я не вижу уведомления (я печатаю его в консоли). Но когда я снова открываю приложение, уведомление печатается.

Ниже приведен мой код регистра уведомлений

    FirebaseMessagesImpl msg = FirebaseMessagesImpl();
         msg.requestPermissions();
    
    //Get configured with firebase messaging to recieve messages
    msg.getMessage().then((_) {
     msg.register().then((String token) {
     print(token);
    
     //Register to the `topic` so we get messages sent to the topic
     msg.topicRegister();
.........
}

FirebaseMessagesImpl

  import 'package:firebase_messaging/firebase_messaging.dart';

  import 'package:http/http.dart' as http;
  import 'dart:convert' as convert;

  class FirebaseMessagesImpl {
    final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

    String serverToken =
        "AAAAAAA:XXXXXXXXX-YYYYYYYY-ZZZZ-BBBBBBBB";

    Future<String> register() async {
      String token = "";
      _firebaseMessaging.getToken().then((t) {
        token = t;
        print("ha: " + t);
      });

      return token;
    }

    Future<void> getMessage() async {
      _firebaseMessaging.configure(
          onMessage: (Map<String, dynamic> message) async {
        print('on message $message');
        //setState(() => _message = message["notification"]["title"]);
      }, onResume: (Map<String, dynamic> message) async {
        print('on resume $message');
        // setState(() => _message = message["notification"]["title"]);
      }, onLaunch: (Map<String, dynamic> message) async {
        print('on launch $message');
        //setState(() => _message = message["notification"]["title"]);
      });
    }

    void topicRegister() {
    // _firebaseMessaging.subscribeToTopic("mobile_admin");
      _firebaseMessaging.subscribeToTopic("puppies");
    }



    void requestPermissions() async
    {
      await _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(sound:true, badge:true, alert:true, provisional:false)
      );
    }

}

Ниже мой 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>FirebaseAppDelegateProxyEnabled</key>
    <false/>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>MY APP NAME</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>$(FLUTTER_BUILD_NAME)</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>$(FLUTTER_BUILD_NUMBER)</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>remote-notification</string>
    </array>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <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>

Ниже AppDelegate.swift

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

      Messaging.messaging().apnsToken = deviceToken
      super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
    }
}

Как некоторые люди рекомендуется в ДРУГИХ ответах SO, я удалил следующий раздел из кода AppDelegate.swift и попытался, но проблема все еще сохраняется. также в руководстве.

Ниже мой код JSon для отправки уведомлений

{
           "notification": {
              "body": "body",
              "title": "title"
           },
           "priority": "high",
           "data": {
            "body": "body",
              "title": "title",
              "click_action": "FLUTTER_NOTIFICATION_CLICK",
              "id": "1",
              "status": "done",
              "image": "https://ibin.co/2t1lLdpfS06F.png"
           },
           "to": "/topics/puppies"
        }

Мои возможности входа следующие

введите описание изображения здесь Я новичок в iOS и не могу понять, что происходит. Я думал, как и в Android, уведомление будет автоматически отображаться в панели уведомлений, когда приложение находится в фоновом режиме или закрыто.

Обновление

По предложению @nandi sh, я изменил файл AppDelegate.swift, как показано ниже

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, UNUserNotificationCenterDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    FirebaseApp.configure()
    GeneratedPluginRegistrant.register(with: self)
    UNUserNotificationCenter.current().delegate = self
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

      Messaging.messaging().apnsToken = deviceToken
      super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
    }
    
    // MARK: - UNUserNotificationCenterDelegate Method
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

     }
}

Затем я получил следующую ошибку:

UNUserNotificationCenter' is only available in iOS 10.0 or newer
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

Обновление

На переднем плане я получаю следующий ответ от приложения, когда выдается уведомление. Это также только в iPhone Симуляторе, а не в реальном устройстве.

{from: /topics/puppies, status: done, id: 1, notification: {body: body, title: title, e: 1, tag: topic_key_9204266xxxxxxx535}, title: title, image: https://ibin.co/2t1lLdpfS06F.png, collapse_key: com.aaa.xxx, body: body, click_action: FLUTTER_NOTIFICATION_CLICK}

Ответы [ 2 ]

0 голосов
/ 06 августа 2020

Для фоновых уведомлений вы можете попробовать добавить «Фоновые режимы» возможность, нажав «+ Возможности» в вашем целевом проекте в разделе «Подписание и возможности» и включите Удаленные уведомления , как это предлагается в приведенном ниже документе Apple.

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app

Также в вашем AppDelegate.swift вы должны добавить как показано ниже:

class AppDelegate: FlutterAppDelegate , UNUserNotificationCenterDelegate {
      override func application(_ application: UIApplication,
          didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
       ....
       UNUserNotificationCenter.current().delegate = self
       ....
    }
    ....

    // MARK: - UNUserNotificationCenterDelegate Method
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

     }
}
0 голосов
/ 05 августа 2020

Во-первых, если вы используете Firebase Cloud Messaging для уведомления, android получит уведомление, когда приложение открыто или закрыто. Но на стороне iOS iOS использует APN's (Apple Push Notification).

* - Вам следует попробовать реальное устройство . На эмуляторах iOS получать уведомления нестабильно. На *

На консоли firebase от go до Settings > Cloud Messaging > iOS Application Configuration затем добавьте свой ключ идентификации APN из панели разработчика Apple. Вы можете увидеть на этот документ .

Также вы должны добавить "content_available": true в свои полезные данные уведомления.

Здесь есть пример:

{
  "to": "/topics/topic_name",
  "content_available": true,
  "notification": {
    "title": "TITLE TEXT",
    "body": "BODY TEXT",
    "content_available": true
  },
  "data": {
    "body": "BODY TEXT",
    "title": "TITLE TEXT",
    "click_action": "FLUTTER_NOTIFICATION_CLICK"
  }
}
...