如何在Flutter中实现赛事结果提交触发的定向推送通知?
解决方案:基于Firebase Cloud Functions实现自动化推送触发
核心思路
利用Firebase Firestore的实时触发器结合Cloud Functions,实现「用户提交赛事结果」事件自动触发「给对手发推送通知」的流程,完全无需手动指定设备组或定时任务。
具体实现步骤
1. 设计Firestore数据结构
在Firestore中创建两个核心集合:
users:存储用户基础信息,必填字段包括userId(用户唯一标识)和fcmToken(设备推送令牌),用户登录或设备token更新时同步写入。matchResults:存储赛事结果提交记录,每个文档需包含:matchId:关联的赛事IDsubmitterId:提交结果的用户IDopponentId:对手用户IDstatus:结果状态(如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
相关产品推荐
相关产品推荐

