Smelly Potato
Smelly Potato

Reputation: 413

POST request body undefined with firestore query

I have the following firebase cloud function that check if the username exists in any firestore doc. I used POST request on client side with Context-Type: application/JSON

exports.login = functions.https.onRequest((request, response) => {
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    console.log(request.body);
    let query = admin.firestore().collection("admin").where("username", "==", request.body.username);
    query.get().then(snapshot => {
        let loginStatus = false;
        if (snapshot.length > 0) loginStatus= true;
        response.send(loginStatus);
        return;
    }).catch();
    response.send(<NOT_IMPORTANT>);
})

if I commented let query = admin..., I can log request.body properly. But with that line exists, request.body becomes undefined, and I can't use it in query. If I hardcode request.body.username to "123" in query, it also works fine and return corresponding docs. Any thing I did wrong?

Upvotes: 0

Views: 483

Answers (1)

JeremyW
JeremyW

Reputation: 5272

I believe your issue is likely due to the fact that you are using an asynchronous command, by time your .get() is fully evaluated, your response.send(<NOT_IMPORTANT>) has already fired, and has closed that req/res.

You need to remove the response.send(<NOT_IMPORTANT>); from the end of your function. Give your .get() query time to run.

Also related to the topic... While your database is small, it's probably not an issue... but I recommend you follow best practices to ensure your cloud function has enough time to run by returning your promise. Those docs include the explanation:

By returning the result of .set(), your function is guaranteed to keep running until the asynchronous work of writing the string to the database is fully completed

exports.hello = functions.database.ref('/hello').onWrite(event => {
    // set() returns a promise. We keep the function alive by returning it.
    return event.data.ref.set('world!').then(() => {
        console.log('Write succeeded!');
    });
});

So what I'm suggesting is:

exports.login = functions.https.onRequest((request, response) => {
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    let query = admin.firestore().collection("admin").where("username", "==", request.body.username);
    return query.get().then(snapshot => {
        let loginStatus = false;
        if (snapshot.length > 0) loginStatus= true;
        response.send(loginStatus);
    }).catch(err => {
        console.log(err);
    });
})

Upvotes: 1

Related Questions