Search code examples
typescriptfirebaseasync-awaitgoogle-cloud-functionses6-promise

Refactoring typescript cloud function to use promise chaining


I am an android developer with little to no experience in web. I wrote a cloud function to register user. but is too nested. I know that I can use promise chaining or async/await. when i tried to use async vs code gives error that, it cannot find name, async, the target is ES6. when i tried chaining promises, it is giving warnings like, not all code paths returns a value. This is my code

exports.register = functions.https.onRequest((request, response) => {
    const db = admin.firestore();
    const user: string = request.body['username'];
    const phone: number = request.body['phone'];
    const password: string = request.body['password'];

    return db.collection('rejectedContacts').where('contact', '==', phone).get()
        .then(rejectedContactsSnapShot => {
            if (rejectedContactsSnapShot.size > 0) {
                return response.json(
                    {
                        status: 0,
                        message: `Contact, ${phone} is blocked, please try again with another number`,
                        result: null
                    }
                );
            } else {
                return db.collection('users').where('contacts.phone', '==', phone).get()
                    .then(contactsSnapShot => {
                        if (contactsSnapShot.size > 0) {
                            return response.json(
                                {
                                    status: 0,
                                    message: `Contact, ${phone} is already assigned with an account. Did you forgot your pasword?`,
                                    result: null
                                }
                            );
                        } else {
                            return db.collection('users').add(
                                {
                                    user: user,
                                    password: password,
                                    isBlocked: false,
                                    joiningDate: Date.now(),
                                    phoneVerified: false,
                                    deleted: false,
                                    contacts:
                                        {
                                            phone: phone
                                        }

                                }
                            ).then((writeResult) => {
                                return response.json(
                                    {
                                        result: `User with ID: ${writeResult.id} added.`
                                    }
                                );
                            });
                        }
                    });
            }
        });
});

this is what i tried when changing to promise chaining, but is showing warning that not all code paths return a value

exports.register = functions.https.onRequest((request, response) => {
    const db = admin.firestore();

    const user: string = request.body['username'];
    const phone: number = request.body['phone'];
    const password: string = request.body['password'];

    return db.collection('rejectedContacts').where('contact', '==', phone).get()
        .then(rejectedContactsSnapShot => {
            if (rejectedContactsSnapShot.size > 0) {
                return response.json(
                    {
                        status: 0,
                        message: `Contact, ${phone} is blocked, please try again with another number`,
                        result: null
                    }
                );
            } 
        }).then(notRejected=>{
            return db.collection('users').where('contacts.phone', '==', phone).get()
                    .then(contactsSnapShot => {
                        if (contactsSnapShot.size > 0) {
                            return response.json(
                                {
                                    status: 0,
                                    message: `Contact, ${phone} is already assigned with an account. Did you forgot your pasword?`,
                                    result: null
                                }
                            );
                        } 
                    });
        }).then(numberDoesNotExists=>{
            return db.collection('users').add(
                {
                    user: user,
                    password: password,
                    isBlocked: false,
                    joiningDate: Date.now(),
                    phoneVerified: false,
                    deleted: false,
                    contacts:
                        {
                            phone: phone
                        }

                }
            );
        }).then((writeResult) => {
            return response.json(
                {
                    result: `User with ID: ${writeResult.id} added.`
                }
            );
        });
});

can anyone help me to re-factor this code to use async/await of promise chaining, so that it can be more readable.


Solution

  • Without knowing what you tried, I'm not sure why you got the error in the first place, but a simple transformation of your code to use async/await would be:

    functions.https.onRequest(async (request, response) => {
        const db = admin.firestore();
        const user: string = request.body['username'];
        const phone: number = request.body['phone'];
        const password: string = request.body['password'];
    
        let rejectedContactsSnapShot = await db.collection('rejectedContacts').where('contact', '==', phone).get();
        if (rejectedContactsSnapShot.size > 0) {
            return response.json(
                {
                    status: 0,
                    message: `Contact, ${phone} is blocked, please try again with another number`,
                    result: null
                }
            );
        } else {
            let contactsSnapShot = await db.collection('users').where('contacts.phone', '==', phone).get();
            if (contactsSnapShot.size > 0) {
                return response.json(
                    {
                        status: 0,
                        message: `Contact, ${phone} is already assigned with an account. Did you forgot your pasword?`,
                        result: null
                    }
                );
            } else {
                let writeResult = await db.collection('users').add({
                    user: user,
                    password: password,
                    isBlocked: false,
                    joiningDate: Date.now(),
                    phoneVerified: false,
                    deleted: false,
                    contacts:{
                        phone: phone
                    }
                })
    
                return response.json(
                    {
                        result: `User with ID: ${writeResult.id} added.`
                    }
                );
            }
        }
    });
    

    Note Your code is a pretty big chuck and without more context the code above may contain errors, but this should get you started.