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

React Native迁移Firebase至Database类后出现'undefined is not an object'错误求助

解决React Native中Database类方法报错及导航问题

问题原因分析

你遇到的undefined is not an object (evaluating 'this.codesRef.once')错误主要有两个核心原因:

  • checkCode被定义成了静态方法(带static关键字),静态方法属于类本身而非类的实例,自然无法访问实例属性this.codesRef;
  • 你调用时直接用db.checkCode(这里的db是Database类,不是实例),进一步导致实例属性完全无法被访问。

另外还有一个隐藏的异步逻辑坑:你把codeIsFound的判断写在了firebase.database().ref().once()的回调外面,而once是异步操作,回调还没执行完就会先运行外面的判断,导致结果永远不正确。

解决方案

1. 修改Database.js:转为实例方法+单例模式

把静态方法改为实例方法,同时将Database类导出为单例,确保整个应用使用同一个数据库实例:

var firebase = require('firebase');
if (!firebase.apps.length) {
  firebase.initializeApp({
    apiKey: "key",
    authDomain: "domain",
    databaseURL: "url",
    storageBucket: "bucket",
  });
}

class Database {
  constructor() {
    // 将codesRef初始化放到构造函数中,确保实例创建时就完成初始化
    this.codesRef = firebase.database().ref('codes');
  }

  // 去掉static关键字,转为实例方法
  checkCode(text, navigation) {
    let codeIsFound = false;
    let identifier = '';
    
    this.codesRef.once('value', (db_snapshot) => {
      db_snapshot.forEach((code_snapshot) => {
        if (text === code_snapshot.val().value) {
          codeIsFound = true;
          identifier = code_snapshot.key;
        }
      });

      // 将判断逻辑移到回调内部,确保异步操作完成后再执行
      if (codeIsFound) {
        // this.deleteCode(identifier);
        console.log("code found");
        navigation.navigate('Create');
      } else {
        console.log("code not found");
      }
    });
  };
}

// 导出单例实例,避免重复创建Database对象
const dbInstance = new Database();
module.exports = dbInstance;

2. 修改KeyForm.js:传入导航参数并调用实例方法

现在导入的是Database的单例实例,直接调用实例方法,并把组件的navigation属性传进去:

import React from 'react';
import { StyleSheet, View, TextInput } from 'react-native';
import db from '../Database.js'; // 现在导入的是单例实例

class LoginForm extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <TextInput 
          placeholder="Access Code" 
          returnKeyType="go" 
          onSubmitEditing={(text) => {
            // 把组件的navigation传入checkCode方法
            db.checkCode(text.nativeEvent.text, this.props.navigation)
          }} 
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  // 你的样式定义
});

export default LoginForm;

额外说明

  • 导航问题:不需要使用withNavigation,直接将组件的this.props.navigation作为参数传递给checkCode即可,这样Database类就能调用导航方法了;
  • 异步操作:Firebase的数据库操作都是异步的,所有依赖操作结果的逻辑必须放在回调函数(或者使用Promise/async-await)内部,否则会拿到未更新的变量值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:52:56