React Native数据库验证函数始终返回undefined问题求助
解决React Native中Firebase密钥验证函数返回undefined的问题
兄弟,你这个问题其实是异步操作的典型坑——Firebase的数据库查询是异步执行的,你的isValidCode函数根本没等到查询完成就结束了,所以返回undefined完全是意料之中的事。让我给你拆解问题,再把代码改好:
问题根源
你写的this.codesRef.once('value', (db_snapshot) => { ... })是异步逻辑:当你调用isValidCode时,函数会先执行到once这一行,然后直接结束(因为后面没有其他同步代码),外层的isValidCode函数默认返回undefined。而回调函数里的return codeIsFound要等到Firebase把数据拉回来才会执行,这时候外层函数早就跑完了,那个return根本传不出结果。
解决方案:用Promise/async-await处理异步
我们需要把isValidCode改成返回一个Promise(或者直接用async函数,本质是一样的),这样调用的时候就能等待异步操作完成,拿到正确的布尔值。
第一步:修改Database.js的isValidCode函数
var firebase = require('firebase'); if (!firebase.apps.length) { firebase.initializeApp({ apiKey: "key", authDomain: "domain", databaseURL: "url", storageBucket: "bucket", }); } class Database { constructor() { this.codesRef = firebase.database().ref('codes'); } // 改成返回Promise的函数,或者直接用async/await写法 isValidCode(text) { return new Promise((resolve, reject) => { this.codesRef.once('value', (db_snapshot) => { let codeIsFound = false; let identifier = ""; db_snapshot.forEach((code_snapshot) => { if (text === code_snapshot.val().value) { codeIsFound = true; identifier = code_snapshot.key; } }); // 把验证结果通过resolve返回出去 resolve(codeIsFound); }, (error) => { // 处理查询出错的情况,把错误抛出去 reject(error); }); }); } // 另一种更简洁的async/await写法,你可以二选一 // async isValidCode(text) { // try { // const db_snapshot = await this.codesRef.once('value'); // let codeIsFound = false; // let identifier = ""; // db_snapshot.forEach((code_snapshot) => { // if (text === code_snapshot.val().value) { // codeIsFound = true; // identifier = code_snapshot.key; // } // }); // return codeIsFound; // } catch (error) { // console.error('数据库查询出错:', error); // throw error; // } // } } module.exports = Database;
第二步:修改KeyForm.js的调用逻辑
因为现在isValidCode是异步函数,不能直接像同步函数那样调用,得用await或者.then()来获取结果。我们写一个异步的处理函数:
import React from 'react'; import { StyleSheet, View, TextInput, Alert } from 'react-native'; import { withNavigation } from 'react-navigation'; import database from '../Database.js'; const db = new database(); class LoginForm extends React.Component { constructor(props) { super(props); } // 写一个异步的提交处理函数 handleCodeSubmit = async (inputText) => { try { // 用await等待验证结果 const isCodeValid = await db.isValidCode(inputText); console.log('验证结果:', isCodeValid); // 根据结果做后续操作 if (isCodeValid) { this.props.navigation.navigate('你的目标页面'); } else { Alert.alert('提示', '无效的访问码,请重新输入'); } } catch (error) { console.error('验证过程出错:', error); Alert.alert('错误', '验证失败,请检查网络或稍后重试'); } } render() { return ( <View style={styles.container}> <TextInput style={styles.input} placeholder="Access Code" returnKeyType="go" // 调用异步处理函数 onSubmitEditing={(event) => this.handleCodeSubmit(event.nativeEvent.text)} autoCapitalize="none" autoCorrect={false} /> </View> ); } } const styles = StyleSheet.create({ // 你的样式代码 }); export default withNavigation(LoginForm);
补充说明
- 之前你尝试添加async/await但没成功,大概率是因为只给
isValidCode加了async,但调用的时候没加await,或者没处理Promise的结果。 - 异步操作一定要用Promise或者async/await来处理,不然永远拿不到正确的异步结果。
内容的提问来源于stack exchange,提问作者Michael Hoefler
相关产品推荐
相关产品推荐

