Firebase admin.auth().getUser(uid) зависает (NodeJS)

Я использую admin.auth().getUser(uid) в Firebase Admin SDK (NodeJS) в бессерверном проекте, и он успешно возвращает результат. Но даже несмотря на то, что моя функция возвращает результат, моя лямбда по-прежнему не завершается, и мне приходится использовать 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 (две разные среды разработки, обе с одинаковым результатом)


person user14764    schedule 12.09.2017    source источник


Ответы (1)


Судя по всему, нужно запустить admin.app().delete();, иначе соединение to 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;
}
person user14764    schedule 12.09.2017
comment
+1. Вызов admin.initializeApp() запускает фоновую задачу, которая поддерживает ваш процесс. Вызов app.delete() завершает эту задачу, обеспечивая корректный выход. - person Hiranya Jayathilaka; 13.09.2017
comment
отличное решение! Один из способов сократить повторение вызова admin.app().delete() в двух местах — просто добавить .then после .catch и вызвать admin.app().delete() там, так как последний .then будет выполняться всегда. - person Ariel Salem; 18.04.2019
comment
в конце концов! Я столкнулся с той же проблемой при использовании объектов db Reference и знал, что это должно быть открытое соединение. Я просмотрел документы, но ничего не нашел об этом ???? - person Felipe; 28.04.2021