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

Firebase实时数据库取消点赞置0触发报错问题求助

Firebase Realtime Database 取消点赞置0报错问题解决

问题场景

实现动漫点赞取消功能时,除了将点赞数从1置为0的场景,其他数值更新都正常。点赞流程:新动漫初始点赞数为0,用户点赞后变为1,取消点赞时尝试将其改回0,此时数据库报错,无法完成操作。已排查确认数据类型为数字、GET请求响应正确、请求路径无误,GET和DELETE请求均正常,仅PUT传入0时触发报错。

当前取消点赞代码:

async unlikeAnime(userID, likeID, animeID) {
    const likeCount = await firebase.get(`AnimeList/${animeID}/like.json`);
    firebase.put(`AnimeList/${animeID}/like.json`, parseInt(likeCount.data - 1));
    firebase.delete(`Users/${userID}/likedAnime/${likeID}.json`);
}

排查方向与解决方案

1. 检查数据库安全规则

这是最常见的触发原因:你的Firebase安全规则可能限制了AnimeList/${animeID}/like字段不能写入0值。比如规则中如果写了类似:

{
  "rules": {
    "AnimeList": {
      "$animeID": {
        "like": {
          ".validate": "newData.isNumber() && newData.val() > 0"
        }
      }
    }
  }
}

这种情况下,写入0会触发验证失败。修改规则为允许0值即可:

{
  "rules": {
    "AnimeList": {
      "$animeID": {
        "like": {
          ".validate": "newData.isNumber() && newData.val() >= 0"
        }
      }
    }
  }
}

2. 改用事务操作替代GET+PUT

原代码的两步操作存在并发风险(比如多个用户同时取消点赞时,可能导致计数错误),而且Firebase官方推荐用事务处理这类计数更新。事务会自动处理数据一致性,同时能避免单独PUT 0时的潜在问题:

async unlikeAnime(userID, likeID, animeID) {
  // 事务更新点赞数,确保不出现负数
  await firebase.database().ref(`AnimeList/${animeID}/like`).transaction(currentCount => {
    const newCount = (currentCount || 0) - 1;
    return newCount >= 0 ? newCount : 0;
  });
  // 删除用户点赞记录
  await firebase.database().ref(`Users/${userID}/likedAnime/${likeID}`).remove();
}

事务会自动重试直到更新成功,同时即使最终结果是0,只要规则允许就能正常写入。

3. 确认字段初始状态

如果新添加的动漫初始时like字段不存在(而非值为0),点赞时设置为1,取消点赞时PUT 0可能触发某些隐式逻辑。可以在创建动漫时显式设置like字段为0,确保字段始终存在,避免潜在的类型或存在性问题。

内容的提问来源于stack exchange,提问作者Surion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:27:26