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

实时数据库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 value of each paired node, then insert the original key + swapped value into the matchingdone node

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 setTimeout to remove it after 30 seconds. We track timers in a Map so 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 & matchingdone insertion: For each pair, we swap their value fields, then write the original key + swapped value to the matchingdone node. Both nodes are removed from waitingroom once paired.

Important Notes

  • If you're running multiple Cloud Function instances, the in-memory activeTimers Map 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:20:41