【问题标题】:Undefined is not an object React Native and FirebaseUndefined 不是对象 React Native 和 Firebase
【发布时间】:2018-01-14 18:27:52
【问题描述】:

我正在使用 CRNA 构建一个 React-Native 应用程序(节点:v9.3.0,npm:4.6.1,RN:0.50.4 React:16.0.0)。

我的控制台给出以下错误: “未定义不是一个对象(评估 'secciones.forEach')”

有bug的代码如下:

async buscarProfesores(secciones) {
    const profesores = [];
    secciones.forEach(seccion => {
        firebase.database().ref(`/Usuarios/${seccion.profesor}`).on('value', async snapshot => {
            const prof = snapshot.val();
            await profesores.push(prof.nombre);
        }); 
    });
    return await profesores;}


async buscarSecciones() {
    try {
        const usuario = firebase.auth().currentUser.uid;
        let secciones;
        await firebase.database().ref(`/Usuarios/${usuario}`)
            .on('value', snapshot => {
                secciones = snapshot.val().secciones;
                return false;
            });
        return secciones;
    } catch (error) {
        console.log(error);
    }
}

我调用buscarProfesores函数是这个sn-p:

async auxiliar() {
    try {
        const secciones = await this.buscarSecciones();
        const profesores = await this.buscarProfesores(secciones);
        const data = await this.armarSnapshot(secciones, profesores);
        return data;
    } catch (error) {
        console.log(error);
    }
}

【问题讨论】:

  • 您将未定义的值传递给 buscarProfesores(),但您没有显示该部分代码。
  • 是的,我忘记复制了,帖子已修复@DougStevenson
  • 您在 buscarSecciones() 中的查询结果似乎返回未定义。
  • 是的,因为我使用的是异步和等待,但仍然无法正常工作,我在“console.log() 进行调试”中添加了一些标志,并为 on() 方法提供了资金从查询不工作,至少没有运行很长时间。 @DougStevenson
  • 使用一次(),而不是()。两者有很大区别。

标签: javascript firebase react-native firebase-realtime-database


【解决方案1】:

我想我可以找出代码中的一些问题,

buscarProfesores:

async buscarProfesores(secciones) {
    let profesores = []; // Not 'const', because 'profesores' is not read-only
    secciones.forEach((seccion) => {
        firebase.database().ref(`/Usuarios/${seccion.profesor}`).once('value', (snapshot) => {
            profesores.push(snapshot.val().nombre);
            // It shouldn't be 'async (snapshot) => { ... }', because
            // What you're doing here is not an async operation, you're simply
            // pushing something into an array. If anything is async, it's this:
            //
            // secciones.forEach(async (seccion) => { firebase.database()... });
        });
    });

    // await return profesores
    // Again, there shouldn't be 'await' here, and even if there isn't await here,
    // all you'll get is an empty array, because 'firebase.database()...' is an
    // async operation, it will be executed, but it will take some amount of time,
    // and meanwhile, the rest of the function will be executed at the same time,
    // meaning that, the return statement will be executed immediately, therefore,
    // you have an empty array
}

因此,您应该重新编写 buscarProfesores 函数。你在buscarSecciones() 函数中得到了几乎完美的结果,只需以同样的方式编写这个函数,你就走在了正确的轨道上。但是,不同的是,您要从数据库中获取许多内容并将它们放入此函数中的数组中,您需要Promise.all() 的帮助:

async buscarProfesores(secciones) {
    let promises = [];
    secciones.forEach((seccion) => {
        promises.push(firebase.database().ref(`/Usuarios/${seccion.profesor}`).once('value'));
    });

    await Promise.all(promises)
        .then((results) => {
            let profesores = [];
            results.forEach((result) => {
                profesores.push(result.val().nombre);
            });

            return profesores;
        })
        .catch((error) => {
            console.log(error);
            return [];
        });
}

Promise.all()接受一个promise数组并执行它们,只有当所有promise都执行成功后才会执行.then(),否则会执行.catch()

buscarSecciones()函数没有太大问题,只需将.on改为.once,并删除return false语句

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 2022-01-23
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多