我使用的是react native,我只是将一些数据库函数迁移到了一个单独的文件中,而不是仅仅将它们存储在需要它们的文件中(我已经开始需要在多个文件中使用相同的函数, d宁愿将它们全部放在一个地方)。问题是,应该将一次键与数据库中的一次键进行比较的函数始终返回 undefined 。
我尝试返回函数而不是布尔值,并尝试使用“异步/等待”关键字(对此我了解甚少)。
这是我的代码...
/project/src/components/Database.js
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');
}
isValidCode(text) {
let codeIsFound = false;
let identifier = "";
this.codesRef.once('value', (db_snapshot) => {
db_snapshot.forEach((code_snapshot) => {
//console.log(text, code_snapshot.val().value, text == code_snapshot.val().value);
if (text == code_snapshot.val().value) {
codeIsFound = true;
identifier = code_snapshot.key;
}
});
//console.log(codeIsFound); // this is correct
return codeIsFound; // this always returns undefined
});
};
}
module.exports = Database;
/project/src/components/forms/KeyForm.js
import React from 'react';
import {
StyleSheet,
View,
TextInput,
} 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);
}
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder="Access Code"
returnKeyType="go"
onSubmitEditing={text => {console.log(db.validCode(text.nativeEvent.text))}} // "undefined"
autoCapitalize="none"
autoCorrect={false}
/>
</View>
);
}
}
const styles = StyleSheet.create({\
// yay styles :)
});
export default withNavigation(LoginForm);
每当我在firebase“ once”函数之后放置一个return语句时,它都会返回一个布尔值,但是由于某种原因,它总是错误的。任何帮助将不胜感激!
答案 0 :(得分:1)
解决此问题:每当我在firebase“ once”函数之后放置一个return语句时,它都会返回一个布尔值,但是由于某种原因,它总是错误的。
通过删除.once()
方法代码,您可以清楚地了解为什么是这种情况。该代码的执行方式与下面的代码完全相同。由于.once()
方法的异步性质,return
语句在.once()
解析(完成)之前执行。
isValidCode(text) {
let codeIsFound = false;
let identifier = "";
// .once() goes here
return codeIsFound;
};
您的本能是关于异步/等待的良好本能。要解决您的问题,请执行以下操作:
async isValidCode(text) {
let codeIsFound = false;
let identifier = "";
let db_snapshot = await this.codesRef.once('value');
db_snapshot.forEach(code_snapshot => {
if (text == code_snapshot.val().value) {
codeIsFound = true;
identifier = code_snapshot.key;
}
});
return codeIsFound;
};
然后,该函数将返回一个将被解决(或拒绝)的promise。因此,要使用此代码,请执行以下操作:
isValidCode('something').then(result => {
/* use result here */
};
答案 1 :(得分:0)
once()
返回一个Promise<DataSnapshot>
,这意味着它是异步的,您不能从异步方法返回值。
要解决您的问题,您可以执行以下操作:
isValidCode(text) {
let codeIsFound = false;
let identifier = "";
this.codesRef.once('value', (db_snapshot) => {
db_snapshot.forEach((code_snapshot) => {
//console.log(text, code_snapshot.val().value, text == code_snapshot.val().value);
if (text == code_snapshot.val().value) {
codeIsFound = true;
identifier = code_snapshot.key;
takeValue(codeIsFound);
}
});
});
};
takeValue(value){
console.log(value) //true
}
在这里,您在once()
内创建一个新方法,然后将该值添加为参数。
答案 2 :(得分:0)
根据@randy casburn,问题是相同的。 只是修改@randy提供的解决方案。
async isValidCode(text) { let codeIsFound = false; let identifier = ""; if(await this.codesRef.once function call ) {
Return true;
} else {return false;} };