Flutter Firebase Cloud Messaging - 应用程序在后台时的通知

Posted

技术标签:

【中文标题】Flutter Firebase Cloud Messaging - 应用程序在后台时的通知【英文标题】:Flutter Firebase Cloud Messaging - Notification when app in background 【发布时间】:2020-01-29 13:26:28 【问题描述】:

我目前正在使用 FCM 进行推送通知。当我的应用程序打开时,我会收到通知,但是当应用程序关闭或在后台时 - 在我重新打开应用程序之前我不会收到任何信息。在 XCode 上,我启用了后台获取并启用了远程通知。接下来我应该检查什么?谢谢。

我正在使用firebase_messaging: ^5.1.6

用代码

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async 
        print('message is $message');

        setState(
          () 
            showOverlayNotification((context) 
              return GestureDetector(
                onTap: () ,
                child: Platform.isios
                    ? MessageNotification(
                        title: message['notification']['title'],
                        body: message['notification']['body'],
                      )
                    : MessageNotification(
                        title: message['notification']['title'],
                        body: message['notification']['body'],
                      ),
              );
              // 
            , duration: Duration(milliseconds: 4000));
          ,
        );
      ,
      onLaunch: (Map<String, dynamic> message) async 
        print('launching');
      ,
      onResume: (Map<String, dynamic> message) async 
        print('resuming');
        print("onResume: $message");
      ,
    );
    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(sound: true, badge: true, alert: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) 
      print("Settings registered: $settings");
    );
    _firebaseMessaging.getToken().then((String token) 
      assert(token != null);
      setState(() 
        _firebaseMessaging.subscribeToTopic('all');
        print('subscribed');
        _homeScreenText = "Push Messaging token: $token";
        _saveDeviceToken(token);
      );
      print(_homeScreenText);
    ); ```


My flutter doctor response is:

```[✓] Flutter (Channel stable, v1.9.1+hotfix.2, on Mac OS X 10.14.6 18G103, locale en-GB)
    • Flutter version 1.9.1+hotfix.2 at /Users/student/flutter
    • Framework revision 2d2a1ffec9 (3 weeks ago), 2019-09-06 18:39:49 -0700
    • Engine revision b863200c37
    • Dart version 2.5.0


[✓] android toolchain - develop for Android devices (Android SDK version 29.0.0)
    • Android SDK at /Users/student/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.0, Build version 11A420a
    • CocoaPods version 1.7.4

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 38.2.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[✓] VS Code (version 1.38.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.4.1

[✓] Connected device (1 available)
    • iPhone • e1100c84b1fc7871a6790337ef23c0fd7af397d5 • ios • iOS 12.4.1

【问题讨论】:

我也面临同样的问题。 你解决了吗? 【参考方案1】:

移动端

我努力了,终于想出了这个解决方案

get_it: ^4.0.4 添加到您的 pubspec.yaml

使用此内容创建文件 Locator.dart:

import 'package:flutter/widgets.dart';

//Open Screen Without Context Service


class NavigationService 
  final  GlobalKey<NavigatorState> navigatorKey =
  new GlobalKey<NavigatorState>();

  navigateTo(String routeName , String name) 
    return navigatorKey.currentState.pushNamed(routeName , arguments: name);
  

  goBack() 
    return navigatorKey.currentState.pop();
  



使用此内容创建文件 Locator.dart:

import 'package:get_it/get_it.dart';
import 'package:MyProject/Services/NavigationService.dart';

//Open Screen Without Context

GetIt locator = GetIt.instance;

void setupLocator() 
  locator.registerLazySingleton(() => NavigationService());

最后你的 main.dart 必须是这样的:

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get_it/get_it.dart';
import 'package:MyProject/Services/NavigationService.dart';
import 'package:MyProject/Utils/locator.dart';

void main() 
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
  runApp(MyApp());


class MyApp extends StatefulWidget 
  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

  @override
  void initState() 
    GetIt.instance.registerSingleton<NavigationService>(NavigationService());
    getMessage();
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: 'App name',
      navigatorKey: locator<NavigationService>().navigatorKey,
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          primaryColorDark: Color(0xff440ABC),
          primaryColor: Color(0xff703FF7),
          primaryColorLight: Color(0xff7e51fa),
          accentColor: Color(0xffc09b01),
          hintColor: Color(0xff616161),
          backgroundColor: Color(0xffFEF9F9),
          bottomAppBarColor: Color(0xffFEF9F9),
          fontFamily: 'Sans'),

      ///MyRequestsScreen
      onGenerateRoute: (routeSettings) 
        switch (routeSettings.name) 
          case 'DestinationScreen':
            return MaterialPageRoute(
                builder: (context) => DestinationScreen());
          default:
            return null;
        
      ,
      home: MenuScreen(),
    );
  

  void getMessage() 
    _firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) async 
      locator<NavigationService>().navigateTo('DestinationScreen', "go");
    , onResume: (Map<String, dynamic> message) async 
      locator<NavigationService>().navigateTo('DestinationScreen', "data");
    , onLaunch: (Map<String, dynamic> message) async 
      locator<NavigationService>().navigateTo('DestinationScreen', "data");
    );
  

服务器端

添加:

"data": 
        "click_action": "FLUTTER_NOTIFICATION_CLICK"
    

在您的 json 中,如下所示:


    "to": "YOUR_PUSH_ID",
    "notification": 
        "body": "YOUR_MESSAGE",
        "OrganizationId": "2",
        "content_available": true,
        "priority": "high",
        "subtitle": "Elementary School",
        "title": "YOUR_TITLE"
    ,
    "data": 
        "click_action": "FLUTTER_NOTIFICATION_CLICK"
    

【讨论】:

干得好,米拉德。我正在使用您建议的代码来配置 FCM 服务。你有更多关于配置的细节吗?我还在挣扎。 @Rocx 谢谢亲爱的 rocx,你有什么问题?【参考方案2】:

发生这种情况可能有两个原因,这是什么以及解决方案是什么,如下所示。

    要将您的插件集成到应用的 iOS 部分,首先您必须按照以下步骤操作,如果未完成,请先执行:

    使用工作区在 Xcode 中打开您的项目。在 Project Navigator 中选择 Runner。在功能选项卡中打开Push NotificationsBackground Modes,并在Background Modes 下启用Background fetchRemote notifications

    如果您需要启用由 FCM iOS SDK 完成的方法转换(例如,以便您可以将此插件与其他通知插件一起使用),请将以下内容删除到您的应用程序的 Info.plist 文件中。

    <key>FirebaseAppDelegateProxyEnabled</key>
    <false/>
    

    之后,在您的 iOS 项目的 AppDelegate.m/AppDelegate.swift 中的 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中删除以下行。

    斯威夫特:

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

    目标-C:

    if (@available(iOS 10.0, *)) 
       [UNUserNotificationCenter currentNotificationCenter].delegate = 
       (id<UNUserNotificationCenterDelegate>) self;
     
    

注意 如果您需要禁用 FCM iOS SDK 完成的方法转换,请添加以下行和代码

【讨论】:

对不起,“删除以下行到 (BOOL) 应用程序......”是什么意思,请您发布一个已注册的,我应该删除该功能还是只放置它,如果该功能下的条件?【参考方案3】:

我设法通过删除对 Flutter Local Notification 插件的任何引用来解决这个问题。我随后删除了:

if (@available(iOS 10.0, *)) 
  [UNUserNotificationCenter currentNotificationCenter].delegate = (id<UNUserNotificationCenterDelegate>) self;
 

来自 ios/runner/AppDelegate.m 或 ios/runner/AppDelegate.swift 文件。

然后通知开始正常工作。

【讨论】:

【参考方案4】:

如果您想通过 firebase 功能进行后台通知 然后你可以查看下面的代码并实现你的输出.... Flutter automatic notification function

【讨论】:

对不起,这个问题不是关于发送通知的。更多的是他们没有在 iOS 上收到。但是,后台通知是通过 android 工作的。

以上是关于Flutter Firebase Cloud Messaging - 应用程序在后台时的通知的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 中的 cloud_firestore 和 firebase_auth 兼容性问题

如何在不使用 Firebase Cloud Messaging 控制台的情况下向 Flutter/Firebase Cloud Messaging 上的特定设备发送通知 [重复]

Firebase Cloud Messaging 无法在带有 Flutter 应用程序的 Android 上运行

Firebase Cloud Firestore 在 Flutter 中获取地图数组

如何使用 graphql 从 Firebase 使用 Flutter 从 Cloud Firestore 获取数据?

Flutter Web App 无法访问 Firebase Cloud Firestore