如何用Firebase结合Expo Notifications向指定用户推送通知?
解决方案:仅用Firebase实现推送通知,及其他替代方案
一、仅借助Firebase实现的方案(无需额外后端)
你完全可以通过Firebase生态内的服务实现需求,首先纠正一个误区:iOS是支持Firebase Cloud Messaging (FCM)的,Expo也提供了官方的FCM集成方案。核心思路是用Firebase Cloud Functions配合FCM完成推送触发,无需搭建独立后端。
具体步骤:
在Expo项目中集成FCM并存储用户推送令牌
- 安装
expo-firebase-messaging包,按照Expo官方指引配置iOS的FCM证书(需在Apple Developer后台和Firebase控制台完成) - 获取当前用户的FCM推送令牌,将其存入Firestore的用户文档中(比如给每个用户文档添加
fcmToken字段)
- 安装
编写Firebase Cloud Function触发推送
有两种触发方式可选:- 方式1:监听Firestore文档删除事件
编写Cloud Function监听Dates集合的文档删除操作,当onCancel函数执行deleteDoc后,自动触发函数获取目标用户的FCM令牌并发送通知:const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.sendCancelNotification = functions.firestore .document("Dates/{dateId}") .onDelete(async (snap, context) => { const deletedDate = snap.data(); const targetUserId = deletedDate.targetUserId; // 假设Dates文档中存储了目标用户ID // 从Firestore获取目标用户的FCM令牌 const userDoc = await admin.firestore().collection("Users").doc(targetUserId).get(); const fcmToken = userDoc.data().fcmToken; if (!fcmToken) return; // 构造通知内容 const message = { notification: { title: "约会已取消", body: "对方取消了你们的约会" }, token: fcmToken }; // 发送通知 return admin.messaging().send(message); }); - 方式2:调用Callable Function主动触发
在onCancel函数中,deleteDoc执行成功后调用Firebase Callable Function,传入目标用户信息,由函数发送通知:
先编写Callable Function:
再在Expo客户端的exports.sendCancelNotification = functions.https.onCall(async (data, context) => { const { targetUserId } = data; const userDoc = await admin.firestore().collection("Users").doc(targetUserId).get(); const fcmToken = userDoc.data().fcmToken; if (!fcmToken) { return { success: false, message: "目标用户无推送令牌" }; } const message = { notification: { title: "约会已取消", body: "对方取消了你们的约会" }, token: fcmToken }; await admin.messaging().send(message); return { success: true }; });onCancel函数中调用:// 先初始化Firebase Functions import { getFunctions, httpsCallable } from "firebase/functions"; const functions = getFunctions(); const sendCancelNotification = httpsCallable(functions, 'sendCancelNotification'); const onCancel = async (dateDetails) => { setIsSubmitting(true); if (!dateDetails.accepted) { await deleteDoc(doc(db, "Dates", dateDetails.dateId)).then(async () => { setIsSubmitting(false); Toast.show({ topOffset: 60, type: "success", text1: "Date Deleted Successfully", text2: " ", }); // 调用Callable Function发送通知 await sendCancelNotification({ targetUserId: dateDetails.targetUserId }); // 假设dateDetails中存储了目标用户ID }); fetchMyDates().then((res) => { setNewDatesOnChild(res); }); } else { setIsSubmitting(false); Alert.alert( "Your order has already been accepted Please call this number to Cancel your order !" ); } };
- 方式1:监听Firestore文档删除事件
二、其他推送通知实现方式
1. 使用Expo官方推送服务(无需FCM)
Expo提供独立的推送服务,无需依赖FCM,只需使用expo-notifications包:
- 步骤:在Expo项目中获取用户的Expo Push Token,存入Firestore
- 配合Firebase Cloud Functions,通过HTTP请求调用Expo推送API发送通知
- 优点:配置比FCM简单,无需Apple和Firebase证书配置;缺点:依赖Expo生态,若后续eject项目会有迁移成本
2. 客户端本地通知(仅给自己发)
如果仅需给当前操作的用户发通知,可直接在onCancel函数中用expo-notifications的presentNotificationAsync方法发送本地通知,但这种方式无法给其他指定用户推送,仅适合本地提示场景。
内容的提问来源于stack exchange,提问作者Zaki Kendil
相关产品推荐
相关产品推荐

