firebase_messaging onResume和onLaunch无法正常工作

时间:2019-05-07 14:43:50

标签: flutter push-notification

当应用程序处于前台时,我会收到通知,而当应用程序处于后台时,我不会收到通知。另外,我使用google-ed / StackOverflow-ed已有2个小时或更长时间,但能够解决此问题。

我的配置是:

  firebase_auth: ^0.10.0
  firebase_messaging: ^5.0.0

清单是这样的:

Manifest

代码如下:

final notifications = new FirebaseMessaging();

class AppNotifications {
  static String fcmToken = '';

  static Future<Null> init() async {
    appLogs("AppNotifications init");

    notifications.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true));

    await configure();

    fcmToken = await notifications.getToken();
    appLogs("FCM TOKEN : " + fcmToken);

    notifications.onTokenRefresh.listen((newToken) {
      fcmToken = newToken;
      appLogs("FCM TOKEN onTokenRefresh: " + fcmToken);
    });

    await updateFCMToken();
  }

  static Future<Null> configure() async {
    appLogs("AppNotifications Configure");

    notifications.configure(onMessage: (msg) {
      appLogs('FCM onMessage: ' + msg.toString());
    }, onLaunch: (lun) {
      appLogs('FCM onLaunch: ' + lun.toString());
    }, onResume: (res) {
      appLogs('FCM onResume: ' + res.toString());
    });
  }

  static Future<Null> updateFCMToken() async {
    auth.currentUser.fcmToken = fcmToken;
    await updateUserInSharedPreference();
  }
}

我正在这样调用函数:

class HomeScreenState extends State<HomeScreen> {


  @override
  void initState() {
    super.initState();

    Future.delayed(Duration(milliseconds: 100), () async {
      await AppNotifications.init();
    });
  }

..... ....

我正在使用邮递员发送通知:

Postman

我的日志:

**(App is Foreground)**  I/flutter (31888): APPLOGS : FCM onMessage: {notification: {title: Test notification title, body: Test notification body}, data: {status: done, id: 1, foo: bar, click_action: FLUTTER_NOTIFICATION_CLICK}}
  **(App is Background)**  W/FirebaseMessaging(31888): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.

扑扑医生:

[✓] Flutter (Channel stable, v1.2.1, on Mac OS X 10.14.4 18E226, locale en-GB)
    • Flutter version 1.2.1 at /Users/Ajay/SDK/flutter
    • Framework revision 8661d8aecd (3 months ago), 2019-02-14 19:19:53 -0800
    • Engine revision 3757390fa4
    • Dart version 2.1.2 (build 2.1.2-dev.0.0 0a7dcf17eb)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/Ajay/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • 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-1248-b01)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.2.1, Build version 10E1001
    • ios-deploy 1.9.4
    • CocoaPods version 1.6.0

[✓] Android Studio (version 3.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 34.0.1
    • Dart plugin version 182.5215
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)

[!] VS Code (version 1.33.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    ✗ Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (1 available)
    • ONEPLUS A5000 • b47e8396 • android-arm64 • Android 9 (API 28)

9 个答案:

答案 0 :(得分:4)

link to plugin docs本节中的firebase_messaging软件包的文档中,他们说您需要在服务器端对{的请求中,将click_action: FLUTTER_NOTIFICATION_CLICK作为“自定义数据”键值对包括在内{1}}和onResume方法被调用。

例如,这里使用the php firebase admin sdk向FCM发送通知,下面是发送通知的代码示例:

Onlaunch

答案 1 :(得分:2)

我花了2天的时间解决此问题,可能对您有所帮助。 通知标签仅用于显示通知。您只能访问onResume或onLaunch上的数据内容。

如果要在onResume或onLaunch中处理通知消息,请将这些消息添加到 data 标签中,然后可以随心所欲。

refer more detail on this link

发送此通知消息

{
       "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": <your token>
    }

您将收到有关恢复或启动的以下信息,您的通知标签此处为空

{notification: {}, data: {image: https://ibin.co/2t1lLdpfS06F.png, google.original_priority: high, google.sent_time: 1560858283888, google.delivered_priority: high, body: body , title: title, click_action: FLUTTER_NOTIFICATION_CLICK, google.message_id: 0:1560858283908500%eefdc741eefdc741, collapse_key: <package>, google.ttl: 2419200, from: <from>, id: 1, status: done}}

您可以使用添加在数据标记中的标题和正文。

答案 2 :(得分:1)

在我的情况下,onResumeonLoad并未触发,因为我在click_action: 'FLUTTER_NOTIFICATION_CLICK'属性下缺少了notification不是 {{ 1}}属性。

一旦我将有效载荷更改为以下格式,dataonResume就开始向我发射。

onLoad

我发现此文档为here

答案 3 :(得分:1)

要通过FCM进行故障排除的另一件事是在您的onMessage处理范围之内。

首先,在onMessage中,打印输出以查看您的设备是否正在接收该消息。通知可能会超出此范围而失败,并且无法显示,因此最好知道通知是否已得到通知。如果是这样,则说明您已正确配置了FCM,并且问题出在UI处理之内。

接下来,检查onMessage打印语句,并确保以后对这些数据的处理正确。我注意到Android数据的结构模式与iOS类型不同-因此这可能导致您错误地解析数据,这可能不会显示通知,也不会引发错误。

这是我的意思的示例:

    _fcm.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        String sender;
        String parsedMessage;

        if (Platform.isAndroid) {
          sender = message['notification']['title'];
          parsedMessage = message['notification']['body'];
        }
        if (Platform.isIOS) {
          sender = message['aps']['alert']['title'];
          parsedMessage = message['aps']['alert']['body'];
        }
      },
    );

您可以看到,根据平台的不同,我解析相同的数据的方式也不同。如果不这样做,该通知将永远不会出现,也永远不会显示失败。

同样,这只是在拆解.ts / .js云功能之前可以尝试的事情。

答案 4 :(得分:0)

您可能会丢失AndroidManifest中的某些元数据(正如您的日志所告诉的那样)。 您需要在清单中添加以下内容:

<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id"/>

好像是duplicate

答案 5 :(得分:0)

Anand saga发表的答案是正确的

您需要在数据部分添加标题和正文。尽管通知有效负载是从后端nodejs API发送的,但onResume和onLaunch仍为空白。

以下是示例有效载荷抖动正在解析为onResume:

on resume {notification: {}, data: {image: https://ibin.co/2t1lLdpfS06F.png, google.original_priority: normal, google.sent_time: 1577389234347, google.delivered_priority: normal, body: "Custom Body", type: OrderDetail, title: "Custom title", click_action: FLUTTER_NOTIFICATION_CLICK, google.message_id: 0:1577389234352165%dfef845edfef845e, collapse_key: <<App NAme>>, google.ttl: 2419200, from: 790713779055, id: "5e050c04c308f6abb5a60b2e"}}

典型的飞镖配置将如下所示。

firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print('on message ${json.encode(message['data']['title'])}');
        redirectScreenOnLoad(message);
      },

      onResume: (Map<String, dynamic> message) async {
        firebaseMessaging.onTokenRefresh;
        print('on resume $message');
        redirectScreenOnLoad(message);

      },

      onLaunch: (Map<String, dynamic> message) async {
        firebaseMessaging.onTokenRefresh;
//        await API.updateUserApiToGetFCMKey();
        print('on launch $message');
        redirectScreenOnLoad(message);
      },
    );

redirectScreenOnLoad(字符串消息)中,我正在检查输入有效负载并重定向到其他屏幕

答案 6 :(得分:0)

如果您的Android应用程序位于kotlin中,则应将其添加为应用程序活动

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

class Application : FlutterApplication(), PluginRegistrantCallback {

    override fun onCreate() {
        super.onCreate()
        FlutterFirebaseMessagingService.setPluginRegistrant(this);
    }

    override fun registerWith(registry: PluginRegistry?) {
        io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    }
}

并且不要忘记将其添加到Manifist android:name=".Application"

答案 7 :(得分:0)

在此处输入代码

onLaunch: (Map<String, dynamic> msg) {
    print("Called onLaunch");
    print(msg);
    if(msg['data']['screen'].toString() == 'chat') {
     //Navigate to chat screen
    }
    return null;
  },

答案 8 :(得分:0)

Complete guide to handle firebase messaging:

handleMessaging() {
_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    // showNotification(
    //     message['notification']['title'], message['notification']['body']);
    print("onMessage: $message");

    print('Data is: '+ message['data']['screen'].toString());

  },
  onLaunch: (Map<String, dynamic> msg) {
    print("Called onLaunch");
    print(msg);
    print('Data is: '+ msg['data']['screen'].toString());

    if(msg['data']['screen'].toString() == 'Chat Screen') {
      return //Navigate to chatApp();
    }
    return null;
  },
  onResume: (Map<String, dynamic> msg) {
    //(App in background)
    // From Notification bar when user click notification we get this event.
    // on this event navigate to a particular page.
    print(msg);

    // // Assuming you will create classes to handle JSON data. :)
    // Notification ns = Notification(title: msg['title'], body: msg['body']);
    //        
    return null;
  },
  // onMessage: (Map<String, dynamic> msg) {
  // // (App in foreground)
  // // on this event add new message in notification collection and hightlight the count on bell icon.
  // // Add notificaion add in local storage and show in a list.
);

}