Flutter firebase_恢复和启动时的消息不起作用

Flutter firebase_恢复和启动时的消息不起作用,flutter,push-notification,Flutter,Push Notification,当应用程序位于前台时,我会收到通知,但当应用程序位于后台时,我不会收到通知。此外,我有谷歌ed/堆叠溢出大约2小时或以上,但能够解决这个问题 我的配置是: firebase_auth: ^0.10.0 firebase_messaging: ^5.0.0 清单如下所示: final notifications = new FirebaseMessaging(); class AppNotifications { static String fcmToken = ''; st

当应用程序位于前台时,我会收到通知,但当应用程序位于后台时,我不会收到通知。此外,我有谷歌ed/堆叠溢出大约2小时或以上,但能够解决这个问题

我的配置是:

  firebase_auth: ^0.10.0
  firebase_messaging: ^5.0.0
清单如下所示:

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

..... ....

代码如下所示:

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

..... ....
颤振医生:

[✓] 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)

您的AndroidManifest中可能缺少一些元数据(如日志所示)。 您需要将以下内容添加到清单中:

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


在我的例子中,
onResume
onLoad
似乎没有触发,因为我缺少了
click\u操作:
NOTIFICATION
属性下的
,而不是
data
属性

一旦我将有效负载更改为以下格式,
onResume
onLoad
开始为我启动

{
    notification: {
        title: 'Title',
        body: 'Body',
        click_action: 'FLUTTER_NOTIFICATION_CLICK'
    }
}
我发现这是有记录的

如果您是在TypeScript(可能是其他)中进行设置,则需要通过消息的
android.notification.clickAction
属性进行设置。否则,您可能会收到有关属性无效的错误。使用
多播消息的示例如下所示。请注意,它不会从头到尾显示消息构造;仅足以显示设置的上下文
单击操作

//初始化通知
常量通知:admin.messaging.notification={
标题:“你好”,
//虽然“clickAction”属性在此处可用,但它会引发一个关于
//在实际尝试发送通知时具有无效属性。
//相反,“clickAction”属性设置在
//MulticastMessage.android.notification对象。
//clickAction:“颤振\u通知\u单击”
};
//执行其他操作以生成通知
常量消息:admin.messaging.multicast消息={
代币:[],
通知:通知
};
//做其他事情来建立你的信息
//如果正在发送通知,则设置“单击”操作
if(message.notification){
//与现有message.android对象(如果存在)结合使用
message.android=message.android |{};
message.android.notification=Object.assign(message.android.notification |{}{
clickAction:“颤振\u通知\u单击”
});
}

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

如果您想在onResume/onLaunch中处理通知消息,请将这些消息也添加到data标记中,然后您可以做任何您想做的事情

发送此通知消息

{
       "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>
    }
{
“通知”:{
“身体”:“身体”,
“标题”:“标题”
},
“优先级”:“高”,
“数据”:{
“身体”:“身体”,
“标题”:“标题”
“点击动作”:“颤振通知点击”,
“id”:“1”,
“状态”:“完成”,
“图像”:https://ibin.co/2t1lLdpfS06F.png",
},
“致”:
}
您将在Resume或onLaunch上收到以下信息,您的通知标签在此将为空

{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}}
{通知:{},数据:{图片:https://ibin.co/2t1lLdpfS06F.png,google.original_priority:high,google.sent_time:1560858283888,google.delivered_priority:high,body:body,title:title,click_action:flatter_NOTIFICATION_click,google.message_id:0:1560858283908500%eefdc741eefdc741,collapse_key:,google.ttl:2419200,from:,id:1,status:done}}

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

Anand saga发布的答案是正确的

您需要在数据部分添加标题和正文。尽管通知负载是从后端节点API发送的,但在恢复和启动时它将为空

下面是正在解决的有效载荷颤振恢复示例:

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"}}
恢复时{通知:{},数据:{图像:https://ibin.co/2t1lLdpfS06F.png,google.original_priority:normal,google.sent_time:15773898934347,google.delivered_priority:normal,body:“自定义body”,类型:OrderDetail,title:“自定义title”,点击动作:颤振通知,点击,谷歌。消息id:0:157738935352165%dfef845edfef845e,折叠键:,谷歌。ttl:2419200,发件人:790713779055,id:“5e050c04c308f6abb5a60b2e”}
典型的dart配置如下所示

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);
      },
    );
firebaseMessaging.configure(
onMessage:(映射消息)异步{
打印('on message${json.encode(message['data']['title']]))});
重定向屏幕加载(消息);
},
onResume:(映射消息)异步{
firebaseMessaging.onTokenRefresh;
打印('在简历上$message');
重定向屏幕加载(消息);
},
onLaunch:(映射消息)异步{
firebaseMessaging.onTokenRefresh;
//等待API.updateUserApiToGetFCMKey();
打印('on launch$message');
重定向屏幕加载(消息);
},
);

在redirectScreenOnLoad(字符串消息)中,我正在检查输入负载并重定向到不同的屏幕

如果您的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"));
    }
}
别忘了把它加在你的手上
android:name=“.Application”

在本节的firebase\u消息包文档中,他们说您需要将
单击\u操作:颤振\u通知\u单击
作为“自定义数据”要调用的
onResume
Onlaunch
方法的服务器端post请求中的键值对

例如,我使用此处向FCM发送通知,这是发送通知的代码示例:

        $factory = (new Factory)->withServiceAccount('path to firebase keys json file');
                $messaging = $factory->createMessaging();

                $deviceToken = $user->deviceToken;
    $message = CloudMessage::withTarget('token', $deviceToken)
                        ->withNotification(Messaging\Notification::create('title', 'body'))
                        ->withData(['custom-data-key1' => 'custom-data-value1', 'custom-data-key2' => 'custom-data-value2', 'click_action'=>'FLUTTER_NOTIFICATION_CLICK']);
$messaging->send($message);

FCM故障排除的另一个需要添加的内容是在您的
onMessage
处理中

首先,在
on中
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.
);