Firebase Cloud Functions:如何将队列中前两位用户配对至新集合
实现Firebase队列用户配对的云函数方案
要实现当Queued Games集合中文档数≥2时自动配对前两位用户并移至目标集合,你需要结合事务处理(避免竞态条件)和集合查询,下面是完整的云函数实现:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.pairQueuedUsers = functions.firestore .document('Queued Games/{userId}') .onCreate(async (snap, context) => { const db = admin.firestore(); const queuedCollection = db.collection('Queued Games'); // 使用事务确保原子操作,防止多实例重复处理 return db.runTransaction(async (transaction) => { // 查询队列中最早加入的两个用户(需提前给文档添加createdAt时间戳) const querySnapshot = await transaction.get( queuedCollection.orderBy('createdAt').limit(2) ); // 队列不足2人,直接结束 if (querySnapshot.size < 2) { return null; } // 提取前两位用户数据 const [user1Doc, user2Doc] = querySnapshot.docs; const user1Data = user1Doc.data(); const user2Data = user2Doc.data(); // 创建配对文档到目标集合(比如命名为Paired Games) const pairedDocRef = db.collection('Paired Games').doc(); await transaction.set(pairedDocRef, { user1: { id: user1Doc.id, ...user1Data }, user2: { id: user2Doc.id, ...user2Data }, pairedAt: admin.firestore.FieldValue.serverTimestamp() }); // 删除队列中的两个用户文档 await transaction.delete(user1Doc.ref); await transaction.delete(user2Doc.ref); return pairedDocRef.id; }) .catch((error) => { functions.logger.error('配对处理失败:', error); throw error; }); });
关键说明
- 事务的必要性:如果多个用户同时加入队列,多个云函数实例会被触发,事务能保证同一批用户只会被配对一次,避免重复操作或数据冲突。
- 排序逻辑:必须在用户加入队列时,给
Queued Games的文档添加createdAt字段(用admin.firestore.FieldValue.serverTimestamp()设置服务器时间),这样才能按加入顺序取前两位用户。 - 目标集合设计:示例中目标集合名为
Paired Games,你可以根据需求调整,配对文档包含两个用户的ID和数据,方便后续房间逻辑开发。
注意事项
- 确保云函数拥有
Queued Games和目标集合的读写权限,可在firestore.rules中配置对应规则。 - 若队列中用户加入频率极高,可考虑调整云函数的超时时间(默认60秒),避免处理超时。
- 事务失败时Firebase会自动重试,无需额外处理,但要做好错误日志记录,方便排查问题。
内容的提问来源于stack exchange,提问作者Scorch
相关产品推荐
相关产品推荐

