Flutter Push Notifications:无法在后台或关闭应用程序时接收通知 [英] Flutter Push Notifications: Unable to receive notifications in background or when app is closed

查看:465
本文介绍了Flutter Push Notifications:无法在后台或关闭应用程序时接收通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Android和iOS开发一款Flutter应用程序.它具有通知,因此我确实实现了 firebase_messaging API.我正在通过设备ID向某些设备发送通知,也向topics发送通知.

I am developing a flutter app for both Android and iOS. It has notifications, so I did implement the firebase_messaging API. I am sending notifications to certain devices by device ID and sending notifications to topics as well.

我正在测试topics通知发送,在Android中可以100%正常运行.我按照上面提供的链接中的指南进行操作,还实现了iOS设置.但是在iOS中,发送通知后,只有在前台时,应用程序才能接收该通知.这意味着只能通过onMessage.如果该应用程序处于后台或关闭状态,则看不到任何通知(我正在控制台中进行打印).但是当我重新打开该应用程序时,通知会被打印.

I am testing the topics notification sending, which is working 100% fine in Android. I followed the guide in above provided link, implemented iOS setups as well. But in iOS, when the notification is sent, it is being received by app only if it is in foreground. Which means, only via onMessage. If the app is in background or closed, I see no notification (I am printing it in console). But when I reopen the app, the notification gets printed.

下面是我的通知注册代码

Below are my notification register code

    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)
    }
}

正如其他人在其他答案中所建议的那样,我从AppDelegate.swift代码中删除了以下部分并进行了尝试,但仍然存在相同的问题.

As some people recommended in OTHER SO answers, I removed the following section from the AppDelegate.swift code and tried, still the same issue persists.

if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
    }

我也已按照指南将苹果密钥文件上传到Firebase项目cloud messaging部分.

I HAVE uploaded the apple key file to Firebase project cloud messaging section as in the guide as well.

下面是我的JSon代码发送通知

Below is my JSon code sending notifications

{
           "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中一样,当应用程序处于后台或关闭状态时,通知会自动显示在通知栏中.

I am new to iOS and can't figure out whats going on. I thought just like in Android, the notification will auto appear in notification bar when the app is in background or closed.

更新

根据@nandish的建议,我如下更改了AppDelegate.swift文件

As suggestion by @nandish, I changed the AppDelegate.swift file as below

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 Simulator中使用,而不能在真实设备中使用.

In foreground, I am getting the following response from the app when a notification is issued. Thats also only in iPhone Simulator, not in real device.

{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}

推荐答案

对于后台通知,您可以尝试通过点击"+功能"来添加背景模式" 功能. 在您的目标项目下的签名并签名";功能" 标签,并按照下面的Apple文档中的建议启用远程通知.

For Background notifications , you can try adding "Background Modes" capability in by clicking on "+ Capability" on your target project under "Signing & Capabilities" tab and enable Remote notifications as suggested in below apple document.

https://developer.apple.com/documentation/usernotifications/setting_up_a_re_te_app_y_remote_notification

还应在A​​ppDelegate.swift中添加以下内容:

Also in your AppDelegate.swift you should added as below:

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) {

     }
}

这篇关于Flutter Push Notifications:无法在后台或关闭应用程序时接收通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆