当前位置: 首页 > 知识库问答 >
问题:

flutter-用户打开推送通知消息(FCM)后如何执行任务

巴宏恺
2023-03-14

我有Firebase cloud messaging(FCM),可以向我的用户发送消息。

然而,我想做一个场景,如果我的用户点击他们的手机上的通知消息,然后应用程序将打开一个视图或弹出,并做一些后台任务。

这可能吗?

谢谢你

===更新Shady Boshra建议的问题

1)我使用typescript创建google cloud Function的firebase:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
const fcm = admin.messaging();

export const sendNotif = functions.https.onRequest((request, response) => {

   const tokens = request.query.tokens;
   const payload: admin.messaging.MessagingPayload = {
   notification: {
      title: '[TEST-123] title...',
      body: `[TEST-123]  body of message... `,          
      click_action: 'FLUTTER_NOTIFICATION_CLICK',
      tag: "news",
      data: "{ picture: 'https://i.imgur.com/bY2bBGN.jpg', link: 'https://example.com' }"
    }
  };
  const res = fcm.sendToDevice(tokens, payload);
  response.send(res);
});

2)我更新我的移动应用程序代码/Dart:

_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
  print("::==>onMessage: $message");

  message.forEach((k,v) => print("${k} - ${v}"));

  String link = "https://example.com";

  FlutterWebBrowser.openWebPage(url: link, androidToolbarColor: Pigment.fromString(UIData.primaryColor));
  return null;
},

然后我尝试发送推送通知时,应用程序是打开模式。

然而,当我试图调试它时,我找不到数据的内容。它给出以下回复:

I/flutter(30602):::==>onmessage:{notification:{body:[TEST-123]消息正文...,title:[TEST-123]title...},data:{}}

I/flutter(30602):::==>onmessage:{notification:{body:[TEST-123]消息正文...,title:[TEST-123]title...},data:{}}

I/flutter(30602):通知-{正文:[TEST-123]消息正文...,标题:[TEST-123]标题...}

I/flutter(30602):数据-{}

I/flutter(30602):通知-{正文:[TEST-123]消息正文...,标题:[TEST-123]标题...}

I/flutter(30602):数据-{}

可以看到,data的内容为空。

===更新2

如果通过删除双引号来编辑data,则在运行firebase deploy时返回错误:

> functions@ build /Users/annixercode/myPrj/backend/firebase/functions
> tsc

src/index.ts:10:4 - error TS2322: Type '{ title: string; body: string; click_action: string; tag: string; data: { picture: string; link: string; }; }' is not assignable to type 'NotificationMessagePayload'.
  Property 'data' is incompatible with index signature.
    Type '{ picture: string; link: string; }' is not assignable to type 'string'.

10    notification: {
      ~~~~~~~~~~~~

  node_modules/firebase-admin/lib/index.d.ts:4246:5
    4246     notification?: admin.messaging.NotificationMessagePayload;
             ~~~~~~~~~~~~
    The expected type comes from property 'notification' which is declared here on type 'MessagingPayload'


Found 1 error.

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! functions@ build: `tsc`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the functions@ build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/anunixercode/.npm/_logs/2019-08-28T01_02_37_628Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code2

==更新3(对Shady Boshra回答的回应)

下面是我在Flutter上的代码:

  _firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
  print("::==>onMessage: $message");

  message.forEach((k,v) => print("${k} - ${v}"));

  var data = message['notification']['data']['link'];
  print ("===>data_notif = "+data.toString());

  var data2 = message['data']['link'];
  print ("===>data_notif2 = "+data2.toString());
...

在我发送推送通知后,我在调试中刚刚得到以下消息:

The application is paused.
Reloaded 22 of 1277 libraries.
I/flutter (18608): 0
I/flutter (18608): AsyncSnapshot<String>(ConnectionState.active, Tuesday, September 3, 2019, null)
I/flutter (18608): ::==>onMessage: {notification: {body: [TEST-123]  body of message... , title: [TEST-123] title...}, data: {}}
I/flutter (18608): notification - {body: [TEST-123]  body of message... , title: [TEST-123] title...}
I/flutter (18608): data - {}
Application finished.

如您所见,我无法在data中获取link的值

共有1个答案

丌官和泰
2023-03-14

当然,你也可以在Flutter上做。

首先,我希望您在清单中设置这些代码

在后端(node.js)的JSON通知体中添加tag元素。

const payload: admin.messaging.MessagingPayload = {
  notification: {
    title: 'New Puppy!',
    body: `${puppy.name} is ready for adoption`,
    icon: 'your-icon-url',
    tag: 'puppy', 
    data: {"click_action": "FLUTTER_NOTIFICATION_CLICK", "id": "1", "status": "done"}, 
    click_action: 'FLUTTER_NOTIFICATION_CLICK' // required only for onResume or onLaunch callbacks
  }
};

并且在Dart代码中,确保在第一个initState()页面中设置此代码。

_fcm.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        var tag = message['notification']['title']);

        if (tag == 'puppy') 
        {
         // go to puppy page
        } else if (tag == 'catty') 
        {
         // go to catty page
        } 
    },
    onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        // TODO optional
    },
    onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        // TODO optional
    },
  );

我大部分的答案都来自这个博客。

它在博客中提到了当回调触发时,所以要仔细决定将代码设置在哪一个中。

onMessage在应用程序打开并在前台运行时激发。

如果应用程序已关闭,但仍在后台运行,则onResume将触发。

如果应用程序完全终止,则启动onLaunch。

由于您的问题已经更新,请考虑本文中的以下内容

•通知消息-由标题和消息正文组成,到达设备时触发通知系统。也就是说,状态栏中会出现一个图标,通知阴影中会出现一个条目。在发送希望用户看到的信息性消息时,应使用此类通知。

例:

var payload = {
  notification: {
    title: "Account Deposit",
    body: "A deposit to your savings account has just cleared."
  }
};

•数据消息--包含键/值对形式的数据,直接发送到应用程序,而不触发通知系统。在向应用程序静默发送数据时使用数据消息。

例:

var payload = {
  data: {
    account: "Savings",
    balance: "$3020.25"
  }
};

•组合消息--包含一个包含通知和数据的有效载荷。通知显示给用户,数据交付给应用程序。

例:

var payload = {
  notification: {
    title: "Account Deposit",
    body: "A deposit to your savings account has just cleared."
  },
  data: {
    account: "Savings",
    balance: "$3020.25"
  }
};

所以,我认为您将使用第三个,它发送通知和数据在同一时间。

您可以简单地使用dart访问数据,如下所示。

message['data']['account']

当你更新你的问题和我的解决方案没有工作与你在一个良好的方式。我决定自己测试一下,你猜怎么着!它与你的和相同的代码很好地工作。

My Node.js后端代码

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();
const fcm = admin.messaging();

exports.sendNotification = functions.firestore
    .document('orders/{orderId}')
    .onCreate(async snapshot => {

        const order = snapshot.data();

        // Token of my device only
        const tokens = ["f5zebdRcsgg:APA91bGolg9-FiLlCd7I0LntNo1_7b3CS5EAJBINZqIpaz0LVZtLeGCvoYvfjQDhW0Qdt99jHHS5r5mXL5Up0kBt2M7rDmXQEqVl_gIpSQphbaL2NhULVv3ZkPXAY-oxX5ooJZ40TQ2-"];

        const payload = {
            notification: {
                title: "Account Deposit",
                body: "A deposit to your savings account has just cleared."
            },
            data: {
                account: "Savings",
                balance: "$3020.25",
                link: "https://somelink.com"
            }
        };

        return fcm.sendToDevice(tokens, payload);
    });

和省道代码

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

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

    _firebaseMessaging.requestNotificationPermissions();

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

        var data2 = message['data']['link'];
        print ("===>data_notif2 = "+data2.toString());

        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            content: ListTile(
              title: Text(message['notification']['title']),
              subtitle: Text(message['notification']['body']),
            ),
            actions: <Widget>[
              FlatButton(
                child: Text('Ok'),
                onPressed: () => Navigator.of(context).pop(),
              ),
            ],
          ),
        );
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
        // TODO optional
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
        // TODO optional
      },
    );

    _saveDeviceToken();
  }

  /// Get the token, save it to the database for current user
  _saveDeviceToken() async {
    // Get the current user
    String uid = 'jeffd23';
    // FirebaseUser user = await _auth.currentUser();

    // Get the token for this device
    String fcmToken = await _firebaseMessaging.getToken();

    // Save it to Firestore
    if (fcmToken != null) {
      print(fcmToken);
    }
  }

和控制台输出

I/flutter (20959): onMessage: {notification: {title: Account Deposit, body: A deposit to your savings account has just cleared.}, data: {account: Savings, balance: $3020.25, link: https://somelink.com}}
I/flutter (20959): ===>data_notif2 = https://somelink.com

所以我相信问题出在你们的代码里,而不是我给你们的解决方案里。请清楚地寻找您可能存在的问题。希望你找到它并为你工作好。

 类似资料:
  • 我是flutter的新手,我只是试图接收firebase推送通知到我的flutter应用程序。当应用程序关闭时,在后台接收推送通知。但是当应用程序打开时,推送通知正在接收,但它不显示警报通知(如果它打开了,我想在我的应用程序中显示推送通知的标题和正文作为警报)。这是我的代码。 谁能帮我做这个吗?

  • 我编写了一个RESTAPI。NET Core现在需要创建一个推送通知到Firebase Cloud Messaging(FCM)。对于测试,我使用Firebase控制台,但我需要通过编程来完成。我已经通过谷歌浏览了Firebase的文档和一些例子,但我更困惑了。 我认为可以通过常规创建消息,但有人可以发布一个简单的工作示例以便我可以拿起它吗?或者也许,我的理解完全错误?

  • 使用更新的Firebase cloud messaging和swizzling方法,当我的应用程序前景化时,我能够成功地在我的应用程序委托中的方法中接收有效负载。但是,我没有收到任何类型的有效负载,并且当我的应用程序处于后台时,不会被调用,尽管api响应消息已成功发送(见下文) 以下是我发送给FCM api的请求,以触发推送通知 有FCM的回复 这是我的appDelegate代码 我在我的应用程序

  • 以下是我的通知案例:当通知到达时,应用程序可能是前台,后台,或关闭 2.后台:当用户点击通知时,应用程序应显示在前面,并显示主要活动 3.App关闭时:当用户点击通知时,App应打开,并显示主要活动。 当我用设置intent和用设置PendingIntent时。它按预期工作,但当用户点击notification时,它不会调用Main Activity的onCreate方法。 如果您考虑了上面的代码

  • 我是谷歌Chrome推送通知的新手,我刚刚在stackoverflow上阅读了一些问题和答案,我已经用这个简单的推送通知JavaScript结束了。 它只是简单的通知,但我需要打开一个新的窗口与其他网页后点击通知。 我知道这是可能的,但我找不到使用“ServiceWorker”语法的示例。 请帮帮忙。多谢了。

  • 使用Phonegap推送通知,如下所示 http://devgirl.org/2013/07/17/tutorial-implement-push-notifications-in-your-phoneGap-application/ 在使用.apk构建.apk时,我得到了这个错误.. 失败 失败:生成失败,出现异常。 出了什么问题: null 总时间:15.085秒 错误:带有args:/s,/