简体   繁体   English

Firebase函数返回并且promise不会退出函数

[英]Firebase Functions returns and promises do not exit the function

I am still a beginner in the Firebase world and I have been trying to figure out what the problem is with the below code but I failed in all possible ways. 我仍然是Firebase世界的初学者,我一直试图弄清楚下面的代码是什么问题,但我在所有可能的方式都失败了。

The code is supposed to retrieve the uid from the user profile in the database, then use it to update the authentication profile, then again to update the database profile if the authentication profile update was successful. 代码应该从数据库中的用户配置文件中检索uid ,然后使用它来更新身份验证配置文件,如果身份验证配置文件更新成功,则再次更新数据库配置文件。

In index.js I have defined an exported function to deal with POSTed params from HTML forms. index.js我定义了一个导出的函数来处理来自HTML表单的POSTed参数。 The code below defines the handler function in another module file: 下面的代码定义了另一个模块文件中的处理函数:

 exports.auUpdateUserByEmail = (req, res) => {
  // This handler function will retrieve the POSTed params of user profile
  // and will attempt to update the existing user authentication as well as
  // the database profiles.
  //
  // This function accepts the following params:
  // 1. User email   // 2. Phone number   // 3. password   // 4. Display name
  // 5. Photo url   // 6. Disabled Flag
  //

  var db = admin.firestore();

  var uEmail = req.body.userEmail;
  var dName = req.body.displayName;
  var userId = "";

  var newuser = {
    displayName: dName
  }

  console.log("Email passed: " + uEmail);

  // Fetch the user UID by user email...
  res.write('User UID: ' + userId);
  console.log('User UID: ' + userId);

  // attempt to update the user authentication profile...
  return db.collection('Users').where('email', '==', email).get()
  .then(snapshot => {
    snapshot.forEach(doc => {
        var d = doc.data();
        console.log("doc.id: " + doc.id + " - d.email: " + d.email);
        if(d.email == email)
        {
          userId = d.uid;
        }
    });

    return admin.auth().updateUser(userId, newuser);
  }).then(function(userRecord) {
    // The updating was successful... Attempt to update User Details in
    // database User Profile...
    console.log("User Updated Successfully. UID: " + userRecord.uid);
    retUid = userRecord.uid;

    // Create a reference to the Users Database...
    var docRef = db.collection('Users');

    // Update the user profile document.
    return docRef.doc(userRecord.uid).update(newuser);
  }).then(result => {
    // everything went fine... return User UID as a successful result...
    res.write(userId);

    return res.end();

  }).catch(function(error) {
    console.log("doc.update - Error updating user profile in database:", error);
    return res.end();

  });
}

In index.js , I have the following exports definition: index.js ,我有以下导出定义:

var appAuth = express();
//Here we are configuring express to use body-parser as middle-ware.
appAuth.use(bodyParser.urlencoded({ extended: false }));
appAuth.use(bodyParser.json());

appAuth.post('/updateUserByEmail', authusers.auUpdateUserByEmail);

exports.usersAuthFunctions = functions.https.onRequest(appAuth);

I have to say that I got it to work fine to get the uid , update the auth profile, and then update database profile, but it keeps on waiting for the function return. 我不得不说,我让它工作正常,以获取uid ,更新auth配置文件,然后更新数据库配置文件,但它一直在等待函数返回。

Appreciate your valuable help. 感谢您的宝贵帮助。 Thanks. 谢谢。


I have updated the code as below and it does the jobs but returns a blank page as the HTTPS exits before the promises are complete which fires "Error: write after end" error. 我已经更新了下面的代码并且它完成了这些工作,但是在promises完成之前HTTPS退出时会返回一个空白页面,这会触发“Error:write after end”错误。

var fetch_uid = db.collection('Users').where('email', '==', uEmail).get()
  .then(snapshot => {
    // var userId = snapshot.data.uid;

    snapshot.forEach(doc => {
        var d = doc.data();
        console.log("doc.id: " + doc.id + " - d.email: " + d.email);
        if(d.email == uEmail)
        {
          userId = d.uid;

          res.write('User UID: ' + userId);
          console.log('User UID: ' + userId);

        }
    });

    return admin.auth().updateUser(userId, newuser);
  }).then(function(userRecord) {
    // The updating was successful... Attempt to update User Details in
    // database User Profile...
    console.log("User Updated Successfully. UID: " + userRecord.uid);
    retUid = userRecord.uid;

    // Create a reference to the Users Database...
    var docRef = db.collection('Users');

    // Update the user profile document.
    return docRef.doc(userRecord.uid).update(newuser);
  }).then(result => {
    // everything went fine... return User UID as a successful result...
    res.write(userId);

    return;

  }).catch(function(error) {
    console.log("doc.update - Error updating user profile in database:", error);
    return;

  });

  res.end();

A previous answer of mine on Cloud Functions for Firebase HTTP timeout might be of help here: 我之前关于Cloud Functions for Firebase HTTP超时的回答可能对此有所帮助:

Cloud Functions triggered by HTTP requests need to be terminated by ending them with a send() , redirect() , or end() , otherwise they will continue running and reach the timeout. 由HTTP请求触发的云功能需要通过以send()redirect()end()结束来终止,否则它们将继续运行并达到超时。

From your code examples, it looks like your then(){} promise returns are ending with res.end() , but the entire function is returning the Promise from: 从您的代码示例中,看起来您的then(){} promise返回以res.end()结尾,但整个函数返回Promise

return db.collection('Users').where('email', '==', email).get()

Which could be stopping it from ending when you want it to. 这可能会阻止它在你想要的时候结束。 With HTTPS triggers, you don't need to return a Promise to keep the function running, only a result. 使用HTTPS触发器,您不需要返回Promise来保持函数运行,只需要一个结果。

Try removing the return statement from this line: 尝试从此行中删除return语句:

db.collection('Users').where('email', '==', email).get()

Then you just need to ensure that all exit routes (or termination points) end with res.end() or similar, so currently you have 2 termination points: 那么你只需要确保所有的退出路径(或终止点)以res.end()或类似的方式结束,所以目前你有2个终止点:

  }).then(result => {
    // everything went fine... return User UID as a successful result...
    res.write(userId);

    res.status(200).end();
  }).catch(function(error) {
    console.log("doc.update - Error updating user profile in database:", error);

    res.status(500).end();
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM