如何在Swift编写的iOS应用中基于FirebaseCloudMessaging实现用户间推送通知?
iOS基于Firebase Cloud Messaging实现用户间推送通知方案
前置准备
- 确保iOS项目已完成Firebase SDK集成,开启Cloud Messaging功能,在Apple开发者后台配置推送证书并同步至Firebase控制台
- 客户端需获取用户的FCM Token,并与用户UID绑定存储到Firebase Firestore/Realtime Database中
实现流程
1. 客户端Token管理(Swift)
负责获取、刷新并同步FCM Token到数据库,确保每个用户的Token是最新状态:
import FirebaseMessaging import FirebaseAuth import FirebaseFirestore @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() // 获取初始FCM Token Messaging.messaging().token { token, error in guard let token = token, error == nil else { print("FCM Token获取失败: \(error?.localizedDescription ?? "未知错误")") return } self.syncTokenToFirestore(token: token) } // 监听Token刷新事件 NotificationCenter.default.addObserver( self, selector: #selector(tokenRefreshed), name: .messagingRegistrationTokenRefreshed, object: nil ) return true } @objc private func tokenRefreshed() { guard let refreshedToken = Messaging.messaging().fcmToken else { return } syncTokenToFirestore(token: refreshedToken) } private func syncTokenToFirestore(token: String) { guard let uid = Auth.auth().currentUser?.uid else { return } let db = Firestore.firestore() db.collection("users").document(uid).setData(["fcmToken": token], merge: true) { error in if let error = error { print("Token同步失败: \(error.localizedDescription)") } } } }
2. 服务端触发推送(Cloud Functions + Admin SDK)
由于serverKey已废弃,必须使用Firebase Admin SDK发送推送。以下是通过Cloud Functions监听消息新增事件自动触发推送的示例(Node.js):
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); // 监听messages集合的新增文档,触发推送 exports.sendUserNotification = functions.firestore.document("messages/{messageId}") .onCreate(async (snapshot) => { const messageData = snapshot.data(); const recipientUid = messageData.recipientUid; const senderName = messageData.senderName; const content = messageData.content; // 获取接收方的FCM Token const userDoc = await admin.firestore().collection("users").document(recipientUid).get(); if (!userDoc.exists || !userDoc.data().fcmToken) { functions.logger.error("接收方无有效FCM Token"); return; } const targetToken = userDoc.data().fcmToken; // 构建推送 payload const payload = { notification: { title: `${senderName}的消息`, body: content, sound: "default" }, token: targetToken }; // 发送推送 try { await admin.messaging().send(payload); functions.logger.info("推送发送成功"); } catch (error) { functions.logger.error("推送发送失败: ", error); } });
客户端只需向messages集合写入包含recipientUid、senderName、content的文档,即可触发自动推送。
3. 客户端处理推送接收(Swift)
处理前台展示、用户点击通知的逻辑:
import UserNotifications extension AppDelegate: UNUserNotificationCenterDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 申请推送权限 UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in if granted { DispatchQueue.main.async { application.registerForRemoteNotifications() } } } UNUserNotificationCenter.current().delegate = self return true } // 前台收到通知时的展示逻辑 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .sound, .badge]) } // 用户点击通知后的跳转逻辑 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // 根据userInfo中的参数跳转到对应聊天界面 completionHandler() } }
关键注意事项
- 禁止使用已废弃的serverKey,必须通过Firebase Admin SDK发送推送
- FCM Token会因重装应用、系统更新等情况变化,需确保实时同步到数据库
- Cloud Functions需配置正确的权限,确保能读取Firestore用户数据并调用Messaging API
- iOS 10+必须使用
UserNotifications框架处理推送,不再支持旧的UIApplicationDelegate推送回调方法
内容的提问来源于stack exchange,提问作者user28587447
相关产品推荐
相关产品推荐

