You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现赛事结果提交触发的定向推送通知?

解决方案:基于Firebase Cloud Functions实现自动化推送触发

核心思路

利用Firebase Firestore的实时触发器结合Cloud Functions,实现「用户提交赛事结果」事件自动触发「给对手发推送通知」的流程,完全无需手动指定设备组或定时任务。

具体实现步骤

1. 设计Firestore数据结构

在Firestore中创建两个核心集合:

  • users:存储用户基础信息,必填字段包括userId(用户唯一标识)和fcmToken(设备推送令牌),用户登录或设备token更新时同步写入。
  • matchResults:存储赛事结果提交记录,每个文档需包含:
    • matchId:关联的赛事ID
    • submitterId:提交结果的用户ID
    • opponentId:对手用户ID
    • status:结果状态(如pending_confirmation表示待确认)
    • resultDetails:具体赛事结果(比分、胜负等)

2. 编写Cloud Functions触发器(Node.js)

创建Firestore触发器,当matchResults集合新增文档时自动执行推送逻辑:

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

// 监听赛事结果提交事件,触发推送
exports.sendResultConfirmationNotification = functions.firestore
  .document("matchResults/{resultId}")
  .onCreate(async (snapshot, context) => {
    const resultData = snapshot.data();
    const opponentId = resultData.opponentId;
    
    // 获取对手的FCM Token
    const userDoc = await admin.firestore().collection("users").doc(opponentId).get();
    if (!userDoc.exists) {
      functions.logger.error("对手用户不存在");
      return null;
    }
    const fcmToken = userDoc.data().fcmToken;
    if (!fcmToken) {
      functions.logger.error("对手未绑定推送令牌");
      return null;
    }

    // 构造推送通知内容
    const payload = {
      notification: {
        title: "赛事结果待确认",
        body: `用户${resultData.submitterId}提交了你们的赛事结果,请前往确认`,
        clickAction: "FLUTTER_NOTIFICATION_CLICK"
      },
      data: {
        matchId: resultData.matchId,
        resultId: context.params.resultId,
        type: "result_confirmation"
      }
    };

    // 发送推送通知
    try {
      await admin.messaging().sendToDevice(fcmToken, payload);
      functions.logger.info("推送通知发送成功");
    } catch (error) {
      functions.logger.error("推送失败:", error);
    }
    return null;
  });

3. Flutter端配合实现

  • 提交赛事结果:用户提交结果时,直接将数据写入Firestore的matchResults集合,触发Cloud Functions:
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> submitMatchResult({
  required String matchId,
  required String submitterId,
  required String opponentId,
  required Map<String, dynamic> resultDetails,
}) async {
  await FirebaseFirestore.instance.collection('matchResults').add({
    'matchId': matchId,
    'submitterId': submitterId,
    'opponentId': opponentId,
    'status': 'pending_confirmation',
    'resultDetails': resultDetails,
    'createdAt': FieldValue.serverTimestamp(),
  });
}
  • 接收并处理推送通知:使用firebase_messaging插件监听通知,点击时跳转到结果确认页面:
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

void setupPushNotifications(BuildContext context) {
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    // 前台收到通知时展示弹窗
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(message.notification?.title ?? ''),
        content: Text(message.notification?.body ?? ''),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              // 跳转到结果确认页面
              Navigator.pushNamed(
                context,
                '/result-confirmation',
                arguments: message.data['resultId'],
              );
            },
            child: const Text('去确认'),
          )
        ],
      ),
    );
  });

  // 点击后台通知时的处理
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    Navigator.pushNamed(
      context,
      '/result-confirmation',
      arguments: message.data['resultId'],
    );
  });
}

4. 关键细节处理

  • FCM Token更新:用户登录、设备重启或token失效时,及时更新users集合中的fcmToken,避免推送失败。
  • 权限校验:在Cloud Functions中可添加额外校验(比如确认submitterId确实是赛事参与者),防止恶意提交。
  • 错误重试:若推送失败,可在Cloud Functions中添加重试逻辑,或记录失败日志以便后续排查。

内容的提问来源于stack exchange,提问作者user22302845

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:07:11