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

iOS端Firebase实现添加记录用户自收推送(基于UID)

解决Firebase仅向操作用户发送推送通知的问题

刚接触Firebase碰到这个推送范围的问题太正常啦,主题推送本来就是给所有订阅主题的用户广播消息,所以才会出现全员收到的情况。要实现只给操作添加记录的那个用户发通知,核心思路就是针对单个用户的设备令牌发送定向推送,下面给你一步步拆解实现方法:

1. 绑定存储用户的FCM设备令牌与账号

首先得让每个登录用户的设备令牌和他的Firebase Auth UID关联起来,存到数据库里,这样后续才能精准找到要推送的目标。

在iOS端获取并存储令牌的代码示例:

import FirebaseMessaging
import FirebaseAuth

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // 关联APNs令牌和FCM
    Messaging.messaging().apnsToken = deviceToken
    
    // 获取FCM令牌
    Messaging.messaging().token { token, error in
        if let error = error {
            print("获取FCM令牌失败:\(error.localizedDescription)")
            return
        }
        
        guard let token = token, let currentUserUID = Auth.auth().currentUser?.uid else {
            print("用户未登录或令牌获取失败")
            return
        }
        
        // 将令牌存入Firebase数据库,关联当前用户UID
        let userTokenRef = Database.database().reference()
            .child("users")
            .child(currentUserUID)
            .child("fcmToken")
        
        userTokenRef.setValue(token) { error, _ in
            if let error = error {
                print("存储令牌失败:\(error.localizedDescription)")
            } else {
                print("令牌存储成功")
            }
        }
    }
}

注意:FCM令牌可能会不定期更新,建议在App启动时也检查更新一次令牌,保证数据库里的令牌是最新的。

2. 添加记录时存入操作用户的UID

在客户端添加记录的逻辑里,一定要把当前登录用户的UID一起存入记录中,这样后续Cloud Functions才能知道这条记录是谁加的,找到对应的推送令牌。

iOS端添加记录的代码示例:

import FirebaseDatabase
import FirebaseAuth

func addNewRecord(content: String) {
    guard let currentUserUID = Auth.auth().currentUser?.uid else {
        print("用户未登录,无法添加记录")
        return
    }
    
    // 生成新记录的节点
    let newRecordRef = Database.database().reference()
        .child("records")
        .childByAutoId()
    
    // 记录数据包含内容和添加者UID
    let recordData: [String: Any] = [
        "content": content,
        "addedBy": currentUserUID
    ]
    
    // 写入数据库
    newRecordRef.setValue(recordData) { error, _ in
        if let error = error {
            print("添加记录失败:\(error.localizedDescription)")
        } else {
            print("记录添加成功")
        }
    }
}

3. 用Firebase Cloud Functions触发定向推送

直接在客户端发推送不安全(会暴露FCM API密钥),所以推荐用Cloud Functions,当数据库里有新记录创建时,自动触发推送逻辑,找到对应用户的令牌发通知。

编写Cloud Functions的Node.js代码:

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

// 当records节点下有新记录创建时触发
exports.sendRecordAddedNotification = functions.database.ref('/records/{recordId}')
    .onCreate(async (snapshot, context) => {
        // 获取添加记录的用户UID
        const addedByUID = snapshot.val().addedBy;
        if (!addedByUID) {
            functions.logger.info("记录中未包含添加者UID,跳过推送");
            return null;
        }

        // 从数据库获取该用户的FCM令牌
        const tokenSnapshot = await admin.database().ref(`/users/${addedByUID}/fcmToken`).once('value');
        const fcmToken = tokenSnapshot.val();
        
        if (!fcmToken) {
            functions.logger.info("未找到该用户的FCM令牌,跳过推送");
            return null;
        }

        // 构建推送内容
        const payload = {
            notification: {
                title: "记录已添加",
                body: "你成功创建了一条新记录"
            },
            token: fcmToken
        };

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

写完代码后,用firebase deploy --only functions命令部署到Firebase即可。

额外注意事项

  • 确保iOS端已经正确配置了APNs证书和Firebase推送设置,不然即使推送发送成功,设备也收不到通知。
  • 如果用户有多台设备,可以在数据库里存储一个令牌数组,推送时遍历数组发送给所有关联设备。
  • 权限方面,Cloud Functions默认的服务账号权限足够访问数据库和发送FCM,如果遇到权限问题,可以去Firebase控制台的IAM页面检查配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:35:21