【问题标题】:Firebase admin.auth().getUser(uid) hangs (NodeJS)Firebase admin.auth().getUser(uid) 挂起(NodeJS)
【发布时间】:2018-02-20 18:17:30
【问题描述】:

我在 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;
}

是不是我做错了什么?

请注意,如果我注释掉 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;
}

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

【问题讨论】:

    标签: node.js serverless-framework firebase-admin


    【解决方案1】:

    显然,您需要运行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;
    }
    

    【讨论】:

    • +1。调用admin.initializeApp() 会启动一个后台任务,这就是让您的进程保持活力的原因。调用app.delete() 会终止此任务,确保正常退出。
    • 优秀的解决方案!减少在两个地方重复调用admin.app().delete() 的一种方法是在.catch 之后添加.then 并在那里调用admin.app().delete(),因为最终的.then 将始终运行。
    • 终于!我在使用 db Reference 对象时遇到了同样的问题,并且知道它必须是一个开放的连接。我搜索了文档,但找不到任何相关信息?
    • firebase-admin 版本 10+ 中的语法已更改。您需要使用 deleteApp(auth.app) 而不是 admin.app().delete() 。
    猜你喜欢
    • 2018-01-04
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-04-04
    • 2018-10-29
    相关资源
    最近更新 更多