Аутентификация Google в firebase, показывающая пустой экран Прогрессивное веб-приложение

Я собираюсь создать свое первое прогрессивное веб-приложение, которое использует firebase для хранения данных. Я также использую Gmail как точку входа для всех пользователей, которые будут использовать приложение. Однако я застрял в реализации логина. Ниже приведен мой код для входа в систему:

HTML:

<button md-raised-button color="warn" (click)="logInGoogle()"><md-icon>group</md-icon>Sign in with google to enjoy the app</button> 

ц

logInGoogle(){
    this.authService.loginWithGoogle().then( user => {
      console.log("User is logged in");
      //this.router.navigate(['/addweather']);
    })
    .catch( err => {
      console.log('some error occured');
    })
  }

Здесь служба:

loginWithGoogle() {
    return this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
  }

Также, чтобы проверить состояние auth, у меня есть это в моем конструкторе app.component.ts:

this.authService.afAuth.authState.subscribe(
      (auth) => {
        if(auth === null){
          console.log("Not Logged in.");
          this.router.navigate(['login']);
          this.isLoggedIn = false;
        }
        else {
          console.log("Successfully Logged in.");
          this.isLoggedIn = true;
          this.router.navigate(['']);
        }
      }
    )

Теперь есть несколько вариантов поведения, которые показывает приложение:

  • Эта функция входа в систему отлично работает в браузерах, если я нажимаю кнопку входа в систему, она открывает новое окно, разрешает мне и возвращается на ту же вкладку, на которой открывается приложение.

  • Когда я добавляю приложение на главный экран и пытаюсь снова войти в систему, он предлагает мне следующие параметры:

введите описание изображения здесь

Как только я нажимаю на chrome, он разрешает мне и перенаправляет меня на приложение, но приложение показывает пустой экран, а экран oAuth просто переходит в бесконечное состояние обработки. Почему это происходит? Я имею в виду, что это не должно работать обычным способом, поскольку это сработало, когда приложение было запущено в браузере.

Также при нажатии кнопки входа в систему он не должен запрашивать опцию, как показано на рисунке выше; вместо этого он должен открыть диалог oAuth. Я попытался сделать это также со следующим кодом:

logInGoogle(){
    var newWindow = window.open('https://accounts.google.com/o/oauth2/auth?scope=https://www.google.com/m8/feeds&client_id=9722-j3fstr5sh6pumie.apps.googleusercontent.com&redirect_uri=https://weatherapp321.firebaseapp.com/__/auth/handler&response_type=token', 'name', 'height=600,width=450');

  }

Теперь вместо запроса с параметрами открывается желаемый диалог. Но после авторизации это возвращает меня на страницу входа. Почему это происходит?, когда я уже проверяю состояние auth в app.component.ts и перенаправляет пользователя на домашнюю страницу, если пользователь получает разрешение.

Спасибо, что терпеливы и читали до конца. Помощь будет высоко оценена.

Edit

Как предложил Евгений: Пробовал с помощью signInWithRedirect. Он работал, когда я впервые вошел в систему с небольшой задержкой в ​​2 секунды. Но затем я вышел из системы и попытался войти в систему снова, после того, как вы вошли в систему, я получил пустой экран.

Ответ 1

У меня было почти такое же поведение в моем домашнем веб-приложении. Для себя я решаю это следующими шагами:

  • Я переношу инициализацию firebase в app.module.ts

@NgModule({
    ...
    providers: [
        { provide: APP_INITIALIZER, useFactory: appConfig, deps: [AuthService], multi: true }
    ]
})

export function appConfig(authService) {
    const app = firebase.initializeApp({
        apiKey
        authDomain
    });
    return () => new Promise((resolve, reject) => {
        firebase.auth()
        .onAuthStateChanged(data => {
            if (data) {
              firebase.auth().currentUser.getToken()
                .then((token: string) => authService.setToken(token););
            }
            resolve(true);
        }, error => resolve(true));
    });
}

Ответ 2

Похоже, что на мобильном устройстве приложение открывает аутентификацию, а не новую вкладку текущего браузера, но в новом браузере, поэтому он не может сделать действительное перенаправление обратно в ваш первоначальный браузер после проверки подлинности в Google. Если вы перейдете с переадресацией, вы останетесь в том же браузере, поэтому вам необходимо изменить свой сервис на:

loginWithGoogle() {
    return this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
}

Ответ 3

перенаправление auth не работает на PWA (вероятно, в некоторых случаях использует разные экземпляры браузера). Вы можете обойти это, используя поток pop-up auth:

https://firebase.google.com/docs/auth/web/google-signin

Он будет выглядеть примерно так:

firebase.auth().signInWithPopup(provider).then(function(result) {
  // This gives you a Google Access Token. You can use it to access the Google API.
  var token = result.credential.accessToken;
  // The signed-in user info.
  var user = result.user;
  // ...
}).catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // The email of the user account used.
  var email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  var credential = error.credential;
  // ...
});

Только разность потоков заключается в том, что он запускает всплывающее окно браузера, а не перенаправляет текущий экземпляр. Это упрощает некоторую логику получения результата auth. Если вы предпочитаете сохранять нормальный поток на не-PWA, вы можете определить, было ли приложение запущено с главного экрана:

https://developers.google.com/web/updates/2015/10/display-mode