eleuteron
eleuteron

Reputation: 1983

angular + firebase auth + material = router crashes

The router is not working properly after firebase authentication. The problem is comming from @angular/animations, both importing NoopAnimationsModule or BrowserAnimationsModule the router doesn't work properly

package.json

"dependencies": { "@angular/animations": "^5.2.8", "@angular/cdk": "^5.2.4", "@angular/common": "^5.2.0", "@angular/compiler": "^5.2.0", "@angular/core": "^5.2.0", "@angular/forms": "^5.2.0", "@angular/http": "^5.2.0", "@angular/material": "^5.2.4", "@angular/platform-browser": "^5.2.0", "@angular/platform-browser-dynamic": "^5.2.0", "@angular/router": "^5.2.0", "angularfire2": "^5.0.0-rc.6", "core-js": "^2.4.1", "firebase": "^4.11.0", "rxjs": "^5.5.6", "zone.js": "^0.8.19" }

I'm redirecting to route '/protected' once authenticated with Google, but the page shows the new route component and the previous one: screenshot

The problem must be a compatibilty issue between Angularfire and Material Animations: commenting the import of BrowserAnimationsModule fixes the issue.

To help understand and reproduce, you have:
- StackBlitz project The annoying part is that this example works, but still presents a transitional state where both components are shown.
- A github repository with the minimum of code reproducing the error.
- The app running from the previous repo.

The firebase credentials will stop working once I find the fix, so please use your own.

Thanks in advance.

Upvotes: 2

Views: 567

Answers (1)

Naman Kheterpal
Naman Kheterpal

Reputation: 1840

Eureka! Eureka!

Do to some reason the work you are doing is outside angular scope. So .then in login.component doesn't trigger lifecycle.tick, which will update complete UI. In your app you can see the login component template will disappear after multiple void events (keyboard or mouse input) because it will trigger tick but you cant specify after how may events it will disappear.

This is similar reason for which we used $scope.$apply in angularJs for manually triggering digest cycle.

The angular 4 way of manually doing outsideAngularWork will need modification in login.component as follow

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { NgZone } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  constructor( private router: Router,private zone: NgZone, private afAuth:AngularFireAuth) { }

    login(){
      this.zone.runOutsideAngular(() => {
        this.afAuth
        .auth
        .signInWithPopup(new firebase.auth.GoogleAuthProvider())
        .then(()=>{
            this.zone.run(() => { this.router.navigate(['/protected']);
          });
        })
        .catch(console.error);
      });
    }
}

Hope this will solve issue on your machine too.

Upvotes: 7

Related Questions