开发者问题收集

如何从 Firebase 函数返回承诺和对象?

2020-06-22
214

提醒一下,这是我第一次使用云函数。我有一个云函数,它在验证一些细节后向我的客户端返回一个对象。我还想使用这个函数写入我的 firestore 数据库。但要写入我的数据库,我必须从我的函数返回一个承诺。我该如何做到这两点并让它工作?这是我的代码。

export const verifyDetails = functions.https.onCall(async (data, context) => {

    const chosenUsername = data.username;
    const chosenEmail = data.email;

    const allEmails: string[] = [];
    const allUsernames: string[] = [];

    let usernameExists = false;
    let emailExists = false;

    await admin.firestore().collection('Users').get()
        .then((snapshot) => {
            snapshot.forEach((doc) => {
                allEmails.push(doc.data().email);
                allUsernames.push(doc.data().username);
            })

            allEmails.forEach((email) => {
                if (email === chosenEmail) {
                    emailExists = true;
                }
            });

            allUsernames.forEach((username) => {
                if (username === chosenUsername) {
                    usernameExists = true;
                }
            });

            if (!usernameExists && !emailExists) {
                registerDetails(chosenUsername, chosenEmail);
            }

        })
        .catch((error) => {
            console.log('Error retrieving firestore documents', error);
        });

    return { usernameExists: usernameExists, emailExists: emailExists };

});


export const registerDetails = functions.https.onCall(async (data, context) => {
    return admin.firestore().collection('Users').add({
        email: data.chosenEmail,
        username: data.chosenUsername
    });
});

我尝试使用另一个 https 回调函数并在主函数中调用它。这不会写入我的数据库,但它会返回我的对象​​。请帮忙!

1个回答

分解出 registerDetails 函数的内容,以便两个 onCall 函数都可以使用它...

async function addUser(data) {
  return admin.firestore().collection('Users').add({
    email: data.chosenEmail,
    username: data.chosenUsername
  })
}

现在 verifyDetails 可以像这样使用它...

export const verifyDetails = functions.https.onCall(async (data, context) => {
  let querySnapshot = await admin.firestore().collection('Users').get()
  // code from the OP here.
  // because we used await, the code doesn't have to be in a then block
  
  await addUser({ chosenEmail, chosenUsername })
  return { usernameExists: usernameExists, emailExists: emailExists };
})

并且 registerDetails 可以像这样使用它...

export const registerDetails = functions.https.onCall(async (data, context) => {
  return addUser(data)
})

请注意,verifyDetails 不返回承诺,但它等待异步工作,这也可以工作。

danh
2020-06-22