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

使用Firebase注册用户时触发Maximum call size exceeded错误排查

问题

我正在使用Firebase为网站搭建用户认证功能,认证环节可正常运行。但用户注册成功后,想向Firebase Realtime Database写入该用户的额外信息(Firebase Auth仅支持邮箱和密码字段)。

认证成功后调用的registerUser(uid)函数如下:

function registerUser(uid) {
  const db = getDatabase();
  var name = document.getElementById('firstName').value;
  var surname = document.getElementById('lastName').value;
  var email = document.getElementById('email').value;
  var category = document.querySelector('.category').lastChild;
  var categoryText = category.options[category.selectedIndex].text;

  var utente;
  if (categoryText === "Studente") {
    utente = new Studente(name, surname, email);
    const utenteJSON = JSON.stringify(utente);
    set(ref(db, "Users/" + uid), {
      Studente: utenteJSON,
    })
      .then(() => {
        window.location.href = "viewInserisciMetodoPagamento.html";
      })
      .catch((error) => {
        alert(error);
      })
  } else {
    console.log("shown");
    utente = new Ascoltatore(name, surname, email);
    console.log("not shown");
    const utenteJSON = JSON.stringify(utente);
    set(ref(db, "Users/" + uid), {
      Ascoltatore: utenteJSON,
    })
      .then(() => {
        window.location.href = "viewInserisciMetodoPagamento.html";
      })
      .catch((error) => {
        alert(error);
      })
  }
}

问题仅在用户注册时选择“Ascoltatore”类别时出现:else分支中,代码执行到utente = new Ascoltatore(name, surname, email)后便停止运行。

Ascoltatore是自定义的用户数据存储类,Studente类代码如下(两者结构类似):

import User from './User.js';

export default class Studente extends User {
    constructor(firstName, lastName, email, metodiPagamento = [], titoliStudioList = [], /*materieCompetenzaList = []*/) {
        super(firstName, lastName, email, metodiPagamento);
        this._titoliStudioList = titoliStudioList;
        /*this._materieCompetenzaList = materieCompetenzaList;*/
    }

    get titoliStudioList() {
        return this._titoliStudioList;
    }

    set titoliStudioList(titoloStudio) {
        this._titoliStudioList.push(titoloStudio);
    }

    /* get _materieCompetenzaList() {
         return this._materieCompetenzaList;
     }
 
     set _materieCompetenzaList(materia) {
         this._materieCompetenzaList.push(materia);
     }*/
}

当注释掉materieCompetenzaList相关字段时,流程正常运行;启用该字段时触发“Maximum call size exceeded”错误,请问原因是什么?

原因分析与解决方法

这个错误的核心是JSON.stringify序列化类实例时触发了无限递归,具体原因如下:

  1. getter命名错误导致递归死循环
    你启用的_materieCompetenzaList getter,命名和私有属性this._materieCompetenzaList完全一致。当JSON.stringify尝试读取这个属性时,会调用getter函数,而getter又返回this._materieCompetenzaList,这会再次触发getter调用,形成无限递归,最终超出调用栈大小,抛出错误。

  2. Ascoltatore类触发问题的原因
    Studente类中你注释了_materieCompetenzaList的getter/setter,而Ascoltatore类中保留了这个错误的getter定义,所以实例化Ascoltatore后执行JSON.stringify(utente)时,直接触发了递归死循环。

解决步骤

  • 修正getter命名:把getter的名字改成不带下划线的materieCompetenzaList,和其他属性(比如titoliStudioList)的命名规则保持一致:
get materieCompetenzaList() {
    return this._materieCompetenzaList;
}

set materieCompetenzaList(materia) {
    this._materieCompetenzaList.push(materia);
}

这样JSON.stringify序列化时会正确调用getter获取属性值,不会触发无限递归。

  • 额外优化建议:如果想更精准控制JSON输出,可以在类中定义toJSON方法,手动指定要序列化的属性,避免自动遍历所有getter的问题:
toJSON() {
    return {
        firstName: this._firstName, // 需根据User类的私有属性名调整
        lastName: this._lastName,
        email: this._email,
        metodiPagamento: this._metodiPagamento,
        materieCompetenzaList: this._materieCompetenzaList
    };
}

JSON.stringify会优先调用这个方法,直接返回纯数据对象,彻底避免getter递归的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:35:10