Alex Ironside
Alex Ironside

Reputation: 5059

Make React wait for Firebase query to end

I am making a call to Firebase, to check if user has a property.

If he has, I want him to be redirected to page A, else I want to redirect him to page B.

The problem is I think Firebase takes to long to come back, so React just renders the component with the default value.

My code:

export default class CheckIfHasCurrentTasksComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            questionId: this.props.match.params.id
        };
    }

    async componentDidMount() {
        var uid = firebase.auth().currentUser.uid;
        var AssignedWordRef = await firebase.database().ref('Users').child(uid).child('assignedWork');
        await AssignedWordRef.on('value', snapshot => {
            var question = snapshot.val();
            console.log('question', question);
            if (question.length > 0) {
                this.setState({
                    questionId: question,
                });
                console.log('redirect', this.state.questionId);
            }
            else {
                this.setState({
                    questionId: this.props.match.params.id,
                });
                console.log('No redirect', this.state.questionId);
            }
        })
    }

    render() {
        console.log('questionId', this.state.questionId);
        return <QuestionComponent questionId={this.state.questionId}/>
    }
}

The logs:

questionId -LEU6zUnLTO84KGh3pua     CheckIfHasCurrentTasksComponent.js:35
question -LEU1fr2TmxHFKD3ObG_       CheckIfHasCurrentTasksComponent.js:18
questionId -LEU1fr2TmxHFKD3ObG_     CheckIfHasCurrentTasksComponent.js:35
redirect -LEU1fr2TmxHFKD3ObG_       CheckIfHasCurrentTasksComponent.js:23

The code seems to be running twice for some reason. The id is the one coming from a previous component. The last 3 are the ones from the database.

The confusing part is that they get logged async-like. How can I make it synchronous/wait for the response from Firebase to come back?

The this.props.match.params.id is an id coming from a previous component. This one is acting all right.

Upvotes: 1

Views: 2194

Answers (1)

Aseem Upadhyay
Aseem Upadhyay

Reputation: 4547

The confusing part is that they get logged async-like. How can I make it synchronous/wait for the response from Firebase to come back?

There's an approach where you can make it look synchronous.

You can attach a variable to this class, which by default, is false. Once, you have received the response, you can set that variable to true.

For instance -

this.state.isQuestionIDAvailable=false;

And in your firebase response, ( do take care of this's scope when using it )

this.setState({
    isQuestionIDAvailable: true
 });

You can then attach a condition to your component like -

{this.state.isQuestionIDAvailable && <QuestionComponent />}

Also, if <QuestionComponent/> is the only thing you are rendering you'll not need the curly braces as well. You can write it as

return this.state.isQuestionIDAvailable && <QuestionComponent />

Hope this answers :)

Upvotes: 2

Related Questions