为什么我的react native函数总是返回undefined?

时间:2019-05-19 13:52:32

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

我使用的是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语句时,它都会返回一个布尔值,但是由于某种原因,它总是错误的。任何帮助将不胜感激!

3 个答案:

答案 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;} };