Firebase admin.auth()。getUser(uid)挂起(NodeJS)

use*_*764 5 node.js serverless-framework firebase-admin

我在无服务器项目中的Firebase Admin SDK(NodeJS)中使用admin.auth()。getUser(uid),它确实成功返回了结果。但是,即使我的函数返回了结果,我的lambda仍然没有终止,我必须使用CTRL + C结束它。

这是我的函数的完整代码(在TypeScript中):

public getUser(uid: string): any {
  console.log('FirebaseManager getUser method start');
  const self: FirebaseManager = this;
  const promise: any = self.getDeferred();

  admin.auth().getUser(uid)
  .then(function(userRecord: admin.auth.UserRecord) {
    console.log("Successfully fetched user data:", userRecord);
    promise.resolve(userRecord);
  })
  .catch(function(error: FirebaseError) {
    console.log("Error fetching user data:", error.errorInfo);
    promise.reject('Error getting Firebase user ' + uid);
  });

  return promise.promise;
}
Run Code Online (Sandbox Code Playgroud)

我做错了什么吗?

请注意,如果我注释掉admin.auth()。getUser(uid)块(并用替换promise.resolve("ok")),我的函数便会正确终止。我的意思是,这不会挂起(但是有点没用了^^):

public getUser(uid: string): any {
  console.log('FirebaseManager getUser method start');
  const self: FirebaseManager = this;
  const promise: any = self.getDeferred();

  promise.resolve("ok");

  return promise.promise;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Serverless 1.21.1,Typescript 2.5.2,Node 6.11.3或8.4.0(2个不同的dev环境,两者的结果相同)

use*_*764 6

显然,您需要运行admin.app().delete();,否则与Firebase的连接将保持活动状态,从而防止进程终止。

因此,在我的示例代码中,考虑到运行此函数后不再需要使用Firebase:

public getUser(uid: string): any {
  console.log('FirebaseManager getUser method start');
  const self: FirebaseManager = this;
  const promise: any = self.getDeferred();

  admin.auth().getUser(uid)
  .then(function(userRecord: admin.auth.UserRecord) {
    console.log("Successfully fetched user data:", userRecord);
    admin.app().delete();
    promise.resolve(userRecord);
  })
  .catch(function(error: FirebaseError) {
    console.log("Error fetching user data:", error.errorInfo);
    admin.app().delete();
    promise.reject('Error getting Firebase user ' + uid);
  });

  return promise.promise;
}
Run Code Online (Sandbox Code Playgroud)

  • +1。调用admin.initializeApp()会启动一个后台任务,这是使进程保持活动状态的原因。调用app.delete()终止此任务,确保正常退出。 (2认同)
  • 天哪,这让我感到难过;谢谢你弄清楚 (2认同)
  • 优秀的解决方案!减少在两个地方调用 `admin.app().delete()` 的一种方法是简单地在 `.catch` 之后添加一个 `.then` 并调用 `admin.app().delete() )` 那里,因为最后的 `.then` 将始终运行。 (2认同)