1

I am fairly new to typescript and I have managed so far with it but I found a weird error/bug that I cannot figure out with async/await.

I have the following code snippet and my problem is that the 'await' clause doesn't work with the .once() function.

async function testFunction(deviceID:string){
    const returnObject:{name:string, description:string, tokens:string[]}[] = [];

    const deviceRef = admin.database().ref('deviceInfo/').orderByChild('id').equalTo(deviceID);

    await deviceRef.once('value', async (payload) => {
        const pushObject:{name:string, description:string, tokens:string[]} = {name:"", description:"", tokens:[]};
        if(payload.exists()){
            const devices = payload.val();
            const keys = Object.keys(devices);

            for(const key of keys){
                pushObject.name = devices[key].name;
                pushObject.description = devices[key].description;
                pushObject.tokens = await getTokens(key);
                returnObject.push(pushObject);

            }
            console.log("Return Object 1:", returnObject);
            return returnObject;

        }
        else{
            return null;
        }

    })
    console.log("Return Object 2:", returnObject);
    return returnObject;
}

This function always returns {name:" ", description: " ", tokens:[]} even though I have 'await' at the start of my deviceRef.once() function.

Also both console.logs print, "Return Object 1" prints the correct object with all the data retrieved from the DB but "Return Object 2" prints an empty array. So it is clear that the await is not waiting for the once() function to complete, I'm just not sure why this is?

Any help or advice would be appreciated

1 Answer 1

3

When using once(), you choose one of two options:

  1. Use the returned promise to get the data from the query.
  2. Pass a callback function as the second argument to get the data from the query.

If you're going to use async/await, I'd go with option 1. Right now it looks like you're using a combination of 1 and 2. Don't bother passing a callback function to once() if you're going to use the promise it returns. That kinda defeats the purpose of using async/await.

const payload = await deviceRef.once('value')
if (payload.exists()) { ... }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, that makes sense and it solved my problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.