【问题标题】:how to implement flutter web push notification如何实现 Flutter Web 推送通知
【发布时间】:2020-07-10 18:35:12
【问题描述】:

我想知道我是否可以在 Flutter Web 中实现推送通知? 我看到我可以使用firbase_messaging 为移动应用创建推送通知,但是可以将它用于网络应用吗?或任何其他替代方法来完成它?

【问题讨论】:

  • 目前,Flutter 团队尚未在 Web 平台上提供 firebase_messaging 插件。该插件仅适用于 Android 和 iOS。此外,您可以在 Flutter 应用程序之外仅使用 html&js 使用 firebase 消息传递,但我认为您不想要这种方式。希望他们也支持网络 firebase_messaging
  • @Mohith7548 我只是希望它发生我不在乎如何?你能告诉我如何用js和html做到这一点吗?因为我从来没有用这些开发过网络
  • 我试过了,但遇到了错误An error occurred while retrieving token: FirebaseError: Messaging: A problem occured while subscribing the user to FCM: Request contains an invalid argument. (messaging/token-subscribe-failed). (messaging/token-subscribe-failed)

标签: flutter flutter-web


【解决方案1】:

我在考虑你已经建立了一个flutter-web项目并且有一个firebase项目。

在flutter项目文件夹中,打开index.html并将这些脚本放在head部分。

<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-messaging.js"></script>

然后,在正文中,在加载 main.dart.js 脚本之前附加代码。

  <script src="./firebase-messaging-sw.js"></script>
  <script src="myjs.js"></script>
  <script src="main.dart.js" type="application/javascript"></script>

(其中 myjs.js 是您要编写代码的任何文件,但 firebase-messaging-sw.js 必须在其中。)

现在,在 index.html 目录中创建两个文件:

  1. firebase-messaging-sw.js
  2. myjs.js(无论您选择什么名称)

在firebase-messaging-sw.js中,只写

console.log("")

在 myjs.js 中(同样,无论您选择什么文件名),编写以下代码:

var firebaseConfig = {
    apiKey: "YOUR_API_KEY",
    authDomain: "~~~~~~",
    databaseURL: "~~~~~",
    projectId: "~~~~~~",
    storageBucket: "~~~~~~",
    messagingSenderId: "~~~~~~",
    appId: "~~~~~~~~~~~~~",
    measurementId: "~~~~~~~~~~~"
};

firebase.initializeApp(firebaseConfig);
firebase.analytics();

var messaging = firebase.messaging()

messaging.usePublicVapidKey('Your Key');

messaging.getToken().then((currentToken) => {
    console.log(currentToken)
})

您可以从 Firebase 控制台的项目设置中找到这些凭据。您将在您添加的网络应用程序中找到 firebaseConfig 详细信息。 对于密钥,您必须生成一个新对。转到项目设置中的 Cloud Messaging,您可以在那里生成一个新对。

当您运行应用程序时(flutter run -d chrome),您可以在控制台日志中找到您的令牌。复制该令牌。

从侧面抽屉的云消息部分,我们可以编写一个新通知。 在标题和文本中输入您喜欢的任何内容。 点击发送测试消息。 粘贴您从控制台复制的令牌,然后单击测试。

你可以看到弹出的通知。

您可以参考this articlefirebase documentation 了解更多信息。

【讨论】:

  • 收到通知就可以了。如何获取通知标题和内容以及如何在 UI 中使用?
  • 我按照上面的说明进行操作。我的网站现在请求发送通知的权限,但是当我通过云消息传递 Web 控制台发送通知时,什么也没有发生。我在本地和外部托管环境中对此进行了测试。我需要编辑 pubspec.yaml 中的任何内容吗?还有其他推荐吗?
  • 要考虑的另一件事是消息传递不适用于 Safari 浏览器。您的 Web 应用程序将显示一个空白页面。这是因为 Safari 不支持 FCM firebase.google.com/support/guides/environments_js-sdk
【解决方案2】:
To implement push notifications and open the app on notification click you need to Change in three files.


1) Firebase-Messaging-sw.js


importScripts("https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/7.23.0/firebase-messaging.js");
firebase.initializeApp({
         apiKey: "",
           authDomain: "",
           projectId: "",
           storageBucket: "",
           messagingSenderId: "",
           appId: "",
           measurementId: ""
});
const messaging = firebase.messaging();


messaging.setBackgroundMessageHandler(function (payload) {
    const promiseChain = clients
        .matchAll({
            type: "window",
            includeUncontrolled: true
        })
        .then(windowClients => {
            for (let i = 0; i < windowClients.length; i++) {
                const windowClient = windowClients[i];
                windowClient.postMessage(payload);
            }
        })
        .then(() => {
            const title = payload.notification.title;
            const options = {
                body: payload.notification.score
              };
            return registration.showNotification(title, options);
        });
    return promiseChain;
});
self.addEventListener('notificationclick', function (event) {
    console.log('notification received: ', event)
});


index.html

<!DOCTYPE html>
<html>
<head>
    <!--
      If you are serving your web app in a path other than the root, change the
      href value below to reflect the base path you are serving from.

      The path provided below has to start and end with a slash "/" in order for
      it to work correctly.

      Fore more details:
      * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
    -->
    <base href="/">

    <meta charset="UTF-8">
    <meta content="IE=Edge" http-equiv="X-UA-Compatible">
    <meta name="description" content="Share pictures and information with other collectors of historical artifacts">

    <!-- iOS meta tags & icons -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="Militrade">
    <link rel="apple-touch-icon" href="icons/Icon-192.png">

    <!-- Favicon -->
    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/>
    <link rel="icon" type="image/x-icon" href="favicon.ico"/>

    <title>Militrade</title>
    <link rel="manifest" href="manifest.json">
</head>
<body>
<script>
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
     navigator.serviceWorker.register("/firebase-messaging-sw.js");
   });
  }
 </script>
<!-- This script installs service_worker.js to provide PWA functionality to
     application. For more information, see:
     https://developers.google.com/web/fundamentals/primers/service-workers -->
<!-- The core Firebase JS SDK is always required and must be listed first -->

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
   https://firebase.google.com/docs/web/setup#available-libraries -->

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-analytics.js"></script>

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-firestore.js"></script>

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-auth.js"></script>

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js"></script>

<script src="https://www.gstatic.com/firebasejs/7.20.0/firebase-storage.js"></script>

<script>
  // Your web app's Firebase configuration
  // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  var firebaseConfig = {
     apiKey: "",
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();
</script>
<script src="main.dart.js" type="application/javascript"></script>
<script type="text/javascript">
    let useHtml = true;
    if(useHtml) {
      window.flutterWebRenderer = "html";
    } else {
      window.flutterWebRenderer = "canvaskit";
    }
  </script>



<script>
    if ("serviceWorker" in navigator) {
      window.addEventListener("load", function () {
        navigator.serviceWorker.register("/flutter_service_worker.js");
        navigator.serviceWorker.register("/firebase-messaging-sw.js");
      });
    }
  </script>


</body>
</html>

then create push_notification_services.dart file for send push notification


import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;

final String serverToken =
    '';

Future<Map<String, dynamic>> sendPushNotification(
    {@required String message,
    @required String fcmToken,
    @required String title}) async {
  print(fcmToken);

  await http.post(
    Uri.parse('https://fcm.googleapis.com/fcm/send'),
    headers: <String, String>{
      'Content-Type': 'application/json',
      'Authorization': 'key=$serverToken',
    },
    body: jsonEncode(
      <String, dynamic>{
        'notification': <String, dynamic>{
           "click_action" : ".EditPostPage",
          'body': message,
          'title': '$title',
          'sound': 'default'
        },
        'priority': 'high',
        'data': <String, dynamic>{
          'click_action': 'FLUTTER_NOTIFICATION_CLICK',
          'id': '1',
          'status': 'done'
        },
        'to': fcmToken.toString().trim(),
      },
    ),
  );
  final Completer<Map<String, dynamic>> completer =
      Completer<Map<String, dynamic>>();

 
  return completer.future;
}


After 3 days I can do it and it's properly working well for me. hope it's helpful for you.
 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    相关资源
    最近更新 更多