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

Firebase Auth/端点响应异常:createNewGroup函数故障求助

问题排查:Firebase Node.js应用创建群组异常

问题现象

  • joinGroup() 功能运行完全正常
  • createNewGroup() 存在两个异常:
    1. 用户认证后首次调用时,Firestore中已成功创建新群组,但前端.then(response => {})内的响应处理逻辑完全不执行
    2. 后续再次调用时,fetchWithAuth无法获取Firebase认证令牌

前端代码

function createNewGroup() {
    console.log("Attempting to create group...");
    const groupId = document.getElementById('group').value;
    fetchWithAuth(`${endpointBaseUrl}/create-new-group`, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({ groupId })
    })
    .then(response => {
        console.log("Received response from fetch request inside createNewGroup");
        console.log(response);
        if (response.success) {
            console.log("Successfully created group:", response.groupId);
        } else {
            console.error('Failed to create group:', response.message);
            throw new Error('Failed to join group: ' + response.message);
        }
    })
    .catch(error => {
        console.error('Error creating new group:', error);
    });
}

function joinGroup() {
    const groupId = document.getElementById('group').value;
    if (!groupId) {
        console.error('Group ID is required');
        document.getElementById('response').textContent = 'Please enter a group ID.';
        return;
    }

    console.log('Joining group with ID:', groupId);
    fetchWithAuth(`${endpointBaseUrl}/join-group`, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({ groupId })
    })
    .then(response => {
        console.log("Received response from fetch request inside joinGroup");
        console.log(response);
        if (response.success) {
            console.log("Successfully joined group:", response.groupId);
            document.getElementById('response').textContent = "Successfully joined group: " + response.message;
        } else {
            console.error('Failed to join group:', response.message);
            document.getElementById('response').textContent = "Error joining group: " + response.message;
            throw new Error('Failed to join group: ' + response.message);
        }
    })
    .catch(error => {
        console.error('Error joining group:', error);
        document.getElementById('response').textContent = 'Error joining group: ' + error.message;
    });
}

// Helper function to perform fetch requests with Firebase authentication
function fetchWithAuth(url, options = {}) {
    console.log("Starting fetchWithAuth for URL:", url);
    console.log("Starting fetchWithAuth with options:", options);

    if (!firebase.auth().currentUser) {
        console.error('No authenticated user.');
        return Promise.reject(new Error('No authenticated user.'));
    }

    // Ensure headers are initialized in options to avoid undefined issues
    if (!options.headers) {
        console.log("Headers are empty");
        options.headers = {};
    }

    return firebase.auth().currentUser.getIdToken(true)
    .then(token => {
        console.log("Obtained Firebase ID token.");

        // Safely append the Authorization header to the existing headers
        options.headers['Authorization'] = `Bearer ${token}`;

        console.log("Headers set for request:", options.headers);

        // Perform the fetch inside the then block to ensure headers are set after token retrieval
        return fetch(url, options);
    })
    .then(response => {
        console.log("Received response from fetch request.");

        if (!response.ok) {
            console.error('Network response was not ok:', response);
            throw new Error('Network response was not ok');
        }

        return response.json();
    })
    .then(data => {
        console.log("Parsed JSON data from response:", data);
        return data;
    })
    .catch(error => {
        console.error('Fetching with auth failed:', error);
        throw error;
    });
}

后端代码

// Endpoint to create a new group
app.post("/create-new-group", authenticate, async (req, res) => {
    const newGroupId = generateRandomGroupId();
    console.log("Backend attempting to create group with ID:", newGroupId);
    try {
        await admin.firestore().collection('groups').doc(newGroupId).set({
            members: [req.user.uid]
        });
        res.json({ success: true, groupId: newGroupId, message: "Created group successfully" });
        console.log("Backend created group with ID:", newGroupId);
    } catch (error) {
        console.error("Error creating new group:", error);
        console.log("Backend error when attempting to create group with ID:", newGroupId);
    }
});

// Endpoint to join an existing group
app.post("/join-group", authenticate, async (req, res) => {
    const { groupId } = req.body;
    console.log("Backend attempting to join group with ID:", groupId);
    const groupRef = admin.firestore().collection('groups').doc(groupId);
    try {
        const groupDoc = await groupRef.get();
        if (groupDoc.exists) {
            const members = groupDoc.data().members;
            members.push(req.user.uid);
            await groupRef.update({ members });
            res.json({ success: true, groupId: groupId, message: "Joined group successfully" });
        } else {
            res.status(404).json({ message: "Group not found" });
        }
    } catch (error) {
        console.error("Error joining group:", error);
        res.status(500).json({ success: false, message: "Internal server error" });
    }
});

问题根源与修复方案

核心问题1:后端未处理异常响应

/create-new-group端点的catch块仅打印错误日志,但未向客户端返回任何响应。这会导致前端请求一直处于挂起状态,无法触发.then逻辑;同时未完成的请求会占用连接资源,干扰后续请求的令牌获取流程。

修复后端代码:
在catch块中添加错误响应:

app.post("/create-new-group", authenticate, async (req, res) => {
    const newGroupId = generateRandomGroupId();
    console.log("Backend attempting to create group with ID:", newGroupId);
    try {
        await admin.firestore().collection('groups').doc(newGroupId).set({
            members: [req.user.uid]
        });
        res.json({ success: true, groupId: newGroupId, message: "Created group successfully" });
        console.log("Backend created group with ID:", newGroupId);
    } catch (error) {
        console.error("Error creating new group:", error);
        console.log("Backend error when attempting to create group with ID:", newGroupId);
        // 新增:返回错误响应,避免请求挂起
        res.status(500).json({ success: false, message: "Failed to create group" });
    }
});

次要问题:前端传参冗余

前端createNewGroup中获取并发送了groupId参数,但后端实际使用generateRandomGroupId()生成ID,该参数未被使用,可优化移除:

function createNewGroup() {
    console.log("Attempting to create group...");
    // 移除无用的groupId获取逻辑
    fetchWithAuth(`${endpointBaseUrl}/create-new-group`, {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({}) // 或省略body(若后端无需接收参数)
    })
    .then(response => {
        console.log("Received response from fetch request inside createNewGroup");
        console.log(response);
        if (response.success) {
            console.log("Successfully created group:", response.groupId);
        } else {
            console.error('Failed to create group:', response.message);
            throw new Error('Failed to create group: ' + response.message);
        }
    })
    .catch(error => {
        console.error('Error creating new group:', error);
    });
}

验证效果

  1. 修复后首次调用createNewGroup,前端应能正常接收响应并执行.then内的日志逻辑
  2. 后续重复调用时,fetchWithAuth可正常获取Firebase令牌,请求流程恢复正常

内容的提问来源于stack exchange,提问作者Björn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:49:50