实时数据库Cloud Function开发:waitingroom节点配对逻辑需求
Got it, let's build this Cloud Function for your realtime database's waitingroom node. I'll walk you through a complete implementation that checks all your boxes, with clear explanations for each requirement.
Solution for Realtime Database
waitingroom Matching Cloud Function Core Logic Breakdown
First, let's align the code with your exact requirements:
- When the first child node is added, start a 30-second timer to wait for a matching node
- If multiple nodes are added at once, randomly pair them two at a time; any unpaired nodes stay to wait for new entries
- Nodes that don't get paired within 30 seconds get removed from
waitingroom - After pairing, swap the
valueof each paired node, then insert the original key + swapped value into thematchingdonenode
Full Implementation (Node.js)
Here's the code using Firebase Cloud Functions and Realtime Database, with comments linking to your requirements:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); // Track active timers for unpaired nodes (to cancel if paired early) const activeTimers = new Map(); exports.handleWaitingRoomMatching = functions.database.ref("/waitingroom/{childKey}") .onCreate(async (snapshot, context) => { const currentKey = context.params.childKey; const currentValue = snapshot.val(); // Fetch all nodes currently in the waiting room const waitingRoomSnapshot = await admin.database().ref("/waitingroom").once("value"); const waitingNodes = waitingRoomSnapshot.val() || {}; const allKeys = Object.keys(waitingNodes); // 1. Handle case where this is the first node: start 30-second wait timer if (allKeys.length === 1) { const timerId = setTimeout(async () => { // 3. Remove unpaired node after timeout await admin.database().ref(`/waitingroom/${currentKey}`).remove(); activeTimers.delete(currentKey); }, 30000); activeTimers.set(currentKey, timerId); return; } // 2. Handle multiple nodes: random pairwise matching // Shuffle keys to ensure random pairing const shuffledKeys = [...allKeys].sort(() => Math.random() - 0.5); const pairs = []; const unpairedKeys = []; // Group keys into pairs, collect leftovers for (let i = 0; i < shuffledKeys.length; i += 2) { if (i + 1 < shuffledKeys.length) { pairs.push([shuffledKeys[i], shuffledKeys[i + 1]]); } else { unpairedKeys.push(shuffledKeys[i]); } } // Process each matched pair for (const [keyA, keyB] of pairs) { const valueA = waitingNodes[keyA]; const valueB = waitingNodes[keyB]; // Cancel any active timers for these nodes if (activeTimers.has(keyA)) { clearTimeout(activeTimers.get(keyA)); activeTimers.delete(keyA); } if (activeTimers.has(keyB)) { clearTimeout(activeTimers.get(keyB)); activeTimers.delete(keyB); } // 5. Swap values and insert to matchingdone, then remove from waitingroom await Promise.all([ admin.database().ref(`/matchingdone/${keyA}`).set(valueB), admin.database().ref(`/matchingdone/${keyB}`).set(valueA), admin.database().ref(`/waitingroom/${keyA}`).remove(), admin.database().ref(`/waitingroom/${keyB}`).remove() ]); } // Set timers for unpaired nodes for (const key of unpairedKeys) { if (!activeTimers.has(key)) { const timerId = setTimeout(async () => { await admin.database().ref(`/waitingroom/${key}`).remove(); activeTimers.delete(key); }, 30000); activeTimers.set(key, timerId); } } });
Key Feature Explanations
Let's break down how this code meets each of your needs:
- 30-second wait for first node: When only one node exists, we spin up a
setTimeoutto remove it after 30 seconds. We track timers in aMapso we can cancel them immediately if a matching node joins early. - Random pairwise matching: We shuffle the list of node keys to ensure pairing is random, then group them two at a time. Leftover nodes get their own 30-second timer to wait for future entries.
- Timeout cleanup: Timers automatically remove unpaired nodes after 30 seconds. If a node gets paired before the timeout, we clear the timer to avoid accidental deletion.
- Value swapping &
matchingdoneinsertion: For each pair, we swap theirvaluefields, then write the original key + swapped value to thematchingdonenode. Both nodes are removed fromwaitingroomonce paired.
Important Notes
- If you're running multiple Cloud Function instances, the in-memory
activeTimersMap might not work across instances. For production, store timer metadata (like expiration timestamps) directly in the database instead. - Test edge cases: adding 3+ nodes at once, adding a node 29 seconds after the first, and timeouts to ensure the logic holds up.
- Ensure your Firebase Admin SDK is properly initialized in your Cloud Functions project.
内容的提问来源于stack exchange,提问作者Viru Patel
相关产品推荐
相关产品推荐

