【问题标题】:Send notification to specific user firebase in flutter在颤动中向特定用户firebase发送通知
【发布时间】:2022-06-15 20:01:49
【问题描述】:

当一个用户按下按钮时,如何向另一个用户发送通知?谁能给我一个代码 sn-p?

我知道之前有人问过这个问题,但是,由于有“几个答案”,所以它被关闭了。提供的类似链接没有解释在 flutter 中发送通知。

【问题讨论】:

    标签: android flutter dart


    【解决方案1】:

    为此,您需要 Firebase 云消息传递。

    我的做法是使用 Cloud Function,您可以通过 HTTP 甚至通过 Firestore 触发器触发,如下所示:

    
    // The Firebase Admin SDK to access Firestore.
    const admin = require('firebase-admin');
    admin.initializeApp();
    
    const db = admin.firestore();
    
    /**
     * Triggered by a change to a Firestore document.
     *
     * @param {!Object} event Event payload.
     * @param {!Object} context Metadata for the event.
     */
    exports.messageNotificationTrigger = (change, context) => {
     
      db.collection('users').get().then((snapshot) => {
        snapshot.docs.forEach(doc => {
          
          const userData = doc.data();
          
          if (userData.id == '<YOUR_USER_ID>') {
             admin.messaging().sendToDevice(userData.deviceToken, {
               notification: { 
                 title: 'Notification title', body: 'Notification Body'}
               });
          }
        });
      });
    };
    

    您在 users 集合中注册的每个用户都必须有一个设备令牌,从他们访问应用程序的设备发送。

    在 Flutter 中,使用 FCM 包,这是您将设备令牌发送到 Firebase 的方式:

    // fetch the device token from the Firebase Messaging instance
          // and store it securely on Firebase associated with this user uid
          FirebaseMessaging.instance.getToken().then((token) {
            FirebaseFirestore.instance.collection('users').doc(userCreds.user!.uid).set({
              'deviceToken': token
            });
          });
    
    

    其中 userCredentials.user!.uid 是您使用 Firebase 身份验证 登录到您的应用程序的用户,如下所示:

    UserCredential userCreds = await FirebaseAuth.instance.signInWithCredential(credential);
    

    希望对您有所帮助。

    【讨论】:

    • 感谢您的回复,但这如何让我向特定用户发送通知,而不是消息?
    • 更新了我的答案。您想使用 Firebase 云消息传递;我建议使用 Firebase 身份验证不仅可以通过对用户进行身份验证来保护您的应用,还可以使用 Firebase Auth 提供给您的唯一 UID 为每个用户创建一个唯一文档,同时关联您的设备在您使用时提供的设备令牌做 Firebase Cloud Messaging,并使用它向特定用户发送消息。我就是这样做的,它对我来说非常有效。
    • 谢谢,在哪里可以找到用户 ID?
    • 当您使用 Firebase 身份验证并执行 signInWithCredentials(无论您使用 Gmail、Twitter)或执行 signInWithEmailAndPassword 时,您会得到一个 b>UserCredential 对象。此对象有一个 uid,每个经过身份验证的用户都是唯一的。您应该使用它作为您的用户文档的唯一 ID。
    • Cloud Functions 需要“按需付费”计划,只要您不超过每月 200 万次调用,它是免费的。当然,您可以在没有 Google Cloud 功能的情况下执行此操作 - 您可能需要自己管理一些事情。
    【解决方案2】:

    上述解决方案可行,但是,我的解决方案要简单得多,并且避免添加新技术

    我已经弄清楚如何使用应用内功能向另一台设备发送通知。

    首先,您需要导入必要的包:

    firebase_messaging
    flutter_local_notifications

    注意:您还将使用http

    另请注意:要将通知发送到另一台设备,您必须知道该设备的设备令牌。我更喜欢获取令牌并将其保存在 Firestore 或实时数据库中。这是获取设备令牌的代码。

    String? mtoken = " ";
    
    void getToken() async {
        await FirebaseMessaging.instance.getToken().then((token) {
          setState(() {
            mtoken = token;
          });
        });
      }
    

    令牌将保存在 mtoken 中,您现在可以将其用作后续步骤的令牌。

    下一步是请求向您的应用发送推送通知的权限。

      void requestPermission() async {
        FirebaseMessaging messaging = FirebaseMessaging.instance;
    
        NotificationSettings settings = await messaging.requestPermission(
          alert: true,
          announcement: false,
          badge: true,
          carPlay: false,
          criticalAlert: false,
          provisional: false,
          sound: true,
        );
    
        if (settings.authorizationStatus == AuthorizationStatus.authorized) {
          print('User granted permission');
        } else if (settings.authorizationStatus ==
            AuthorizationStatus.provisional) {
          print('User granted provisional permission');
        } else {
          print('User declined or has not accepted permission');
        }
      }
    

    (如果您在控制台中收到“用户拒绝或未接受权限”,请尝试退出您的应用,在主屏幕中找到图标,按住应用图标,点击“应用信息”,点击“通知”并打开“所有 [应用名称] 通知”。

    您还需要两个函数来加载 Firebase Cloud Messaging 通知和一个监听通知。

    加载 Firebase 云消息通知的代码:

     void loadFCM() async {
        if (!kIsWeb) {
          channel = const AndroidNotificationChannel(
            'high_importance_channel', // id
            'High Importance Notifications', // title
            importance: Importance.high,
            enableVibration: true,
          );
    
          flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
    
          /// Create an Android Notification Channel.
          ///
          /// We use this channel in the `AndroidManifest.xml` file to override the
          /// default FCM channel to enable heads up notifications.
          await flutterLocalNotificationsPlugin
              .resolvePlatformSpecificImplementation<
                  AndroidFlutterLocalNotificationsPlugin>()
              ?.createNotificationChannel(channel);
    
          /// Update the iOS foreground notification presentation options to allow
          /// heads up notifications.
          await FirebaseMessaging.instance
              .setForegroundNotificationPresentationOptions(
            alert: true,
            badge: true,
            sound: true,
          );
        }
      } 
    

    此函数用于侦听 Firebase 云消息传递通知。

    void listenFCM() async {
        FirebaseMessaging.onMessage.listen((RemoteMessage message) {
          RemoteNotification? notification = message.notification;
          AndroidNotification? android = message.notification?.android;
          if (notification != null && android != null && !kIsWeb) {
            flutterLocalNotificationsPlugin.show(
              notification.hashCode,
              notification.title,
              notification.body,
              NotificationDetails(
                android: AndroidNotificationDetails(
                  channel.id,
                  channel.name,
                  // TODO add a proper drawable resource to android, for now using
                  //      one that already exists in example app.
                  icon: 'launch_background',
                ),
              ),
            );
          }
        });
      }
    

    您需要在页面初始化时运行 loadFCM、listenFCM 和 requestPermission。

      void initState() {
        super.initState();
        requestPermission();
        loadFCM();
        listenFCM();
      }
    

    下一步是找到您的Firebase Cloud Messaging API 密钥。这可以简单地通过前往您的 Firebase 项目 > 项目设置 > 云消息传递然后复制 Cloud Messaging API (Legacy) 下的 API 密钥来完成。

    当您拥有 Firebase Cloud Messaging API 密钥后,这是显示通知的代码,给定通知标题、正文和要发送到的设备令牌。

      void sendPushMessage(String body, String title, String token) async {
        try {
          await http.post(
            Uri.parse('https://fcm.googleapis.com/fcm/send'),
            headers: <String, String>{
              'Content-Type': 'application/json',
              'Authorization':
                  'key=REPLACETHISWITHYOURAPIKEY',
            },
            body: jsonEncode(
              <String, dynamic>{
                'notification': <String, dynamic>{
                  'body': body,
                  'title': title,
                },
                'priority': 'high',
                'data': <String, dynamic>{
                  'click_action': 'FLUTTER_NOTIFICATION_CLICK',
                  'id': '1',
                  'status': 'done'
                },
                "to": token,
              },
            ),
          );
          print('done');
        } catch (e) {
          print("error push notification");
        }
      }
    

    现在你可以这样调用这个函数了:

    sendPushMessage('Notification Body', 'Notification Title', 'REPLACEWITHDEVICETOKEN');

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-29
      • 2021-03-18
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多