首页 > 解决方案 > 为什么路线导航只能工作一次?

问题描述

我是离子/角度的新手。如果我点击我,我希望在用户登录之前,登录页面总是出现而不是个人资料页面。问题是这样的。如果我第一次单击我,我会转到登录页面,因为用户没有登录。但是,如果我再次单击,则退出个人资料页面而不是再次退出登录页面。

Profile.page.ts

import { Component , OnInit} from '@angular/core';
import { AuthenticationService } from "../shared/authentication.service";
import { Router } from "@angular/router";

@Component({
  selector: 'app-profile',
  templateUrl: './profile.page.html',
  styleUrls: ['./profile.page.scss'],
})
export class ProfilePage implements OnInit{
  userState:string="";
  constructor(public authService: AuthenticationService, public router: Router) { 
  if(this.authService.isLoggedIn){
    this.userState="Logged;"
    this.router.navigate(['tabs/home']); 
  }
  else{
    this.userState="Not Logged;"
    this.router.navigate(['tabs/login']);
  }
}
ngOnInit() {
}
}

...这是使用 Firebase 方法的服务: authentications-service

import { Injectable, NgZone } from '@angular/core';
import { auth } from 'firebase/app';
import { User } from "./user";
import { Router } from "@angular/router";
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';

@Injectable({
  providedIn: 'root'
})

export class AuthenticationService {
  userData: any;

  constructor(
    public afStore: AngularFirestore,
    public ngFireAuth: AngularFireAuth,
    public router: Router,  
    public ngZone: NgZone 
  ) {
    this.ngFireAuth.authState.subscribe(user => {
      if (user) {
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    })
  }

  // Login in with email/password
  SignIn(email, password) {
    return this.ngFireAuth.signInWithEmailAndPassword(email, password)
  }

  // Register user with email/password
  RegisterUser(email, password) {
    return this.ngFireAuth.createUserWithEmailAndPassword(email, password)
  }

  // Email verification when new user register
  SendVerificationMail() {
    return this.ngFireAuth.currentUser.then(u => u.sendEmailVerification())
    .then(() => {
      this.router.navigate(['verify-email']);
    })
  }

  // Recover password
  PasswordRecover(passwordResetEmail) {
    return this.ngFireAuth.sendPasswordResetEmail(passwordResetEmail)
    .then(() => {
      window.alert('Password reset email has been sent, please check your inbox.');
    }).catch((error) => {
      window.alert(error)
    })
  }

  // Returns true when user is looged in
  get isLoggedIn(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return (user !== null && user.emailVerified !== false) ? true : false;
  }

  // Returns true when user's email is verified
  get isEmailVerified(): boolean {
    const user = JSON.parse(localStorage.getItem('user'));
    return (user.emailVerified !== false) ? true : false;
  }

  // Sign in with Gmail
  GoogleAuth() {
    return this.AuthLogin(new auth.GoogleAuthProvider());
  }

  // Auth providers
  AuthLogin(provider) {
    return this.ngFireAuth.signInWithPopup(provider)
    .then((result) => {
       this.ngZone.run(() => {
          this.router.navigate(['tabs/home']);
        })
      this.SetUserData(result.user);
    }).catch((error) => {
      window.alert(error)
    })
  }

  // Store user in localStorage
  SetUserData(user) {
    const userRef: AngularFirestoreDocument<any> = this.afStore.doc(`users/${user.uid}`);
    const userData: User = {
      uid: user.uid,
      email: user.email,
      displayName: user.displayName,
      photoURL: user.photoURL,
      emailVerified: user.emailVerified
    }
    return userRef.set(userData, {
      merge: true
    })
  }

  // Sign-out 
  SignOut() {
    return this.ngFireAuth.signOut().then(() => {
      localStorage.removeItem('user');
      this.router.navigate(['tabs/login']);
    })
  }

}

登录页面:

import { Component,OnInit } from '@angular/core';
import { Router } from "@angular/router";
import { AuthenticationService } from "../shared/authentication.service";

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})

export class LoginPage implements OnInit {

  constructor(
    public authService: AuthenticationService,
    public router: Router
  ) {}

  ngOnInit() {}

  logIn(email, password) {
    this.authService.SignIn(email.value, password.value)
      .then((res) => {
        if(this.authService.isEmailVerified) {
          this.router.navigate(['tabs/home']);          
        } else {
          window.alert('Email is not verified')
          return false;
        }
      }).catch((error) => {
        window.alert(error.message)
      })
  }

}

应用程序路由.module.ts

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
  },
  { 
    path: 'tabs/home', loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) 
  },
  { 
    path: 'tabs/profile', loadChildren: () => import('./profile/profile.module').then(m => m.ProfilePageModule) 
  },
  { 
    path: 'tabs/search', loadChildren: () => import('./search/search.module').then(m => m.SearchPageModule) 
  },
  {
    path: 'tabs/registration',
    loadChildren: () => import('./registration/registration.module').then( m => m.RegistrationPageModule)
  },
  {
    path: 'verify-email',
    loadChildren: () => import('./verify-email/verify-email.module').then( m => m.VerifyEmailPageModule)
  },
  {
    path: 'tabs/login',
    loadChildren: () => import('./login/login.module').then( m => m.LoginPageModule)
  },

];
@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

应用模块.ts

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule, 
    IonicModule.forRoot(),
    AppRoutingModule,
    AngularFireModule.initializeApp(environment.firebaseConfig),
    AngularFireAuthModule,
    AngularFireDatabaseModule,
    AngularFireStorageModule
  ],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    AngularFirestoreModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

我不知道方法路由器是否有问题,或者我缺少其他一些概念。感谢您的回答 在此处输入图像描述

标签: angularionic-framework

解决方案


我建议您在使用 angularFire 时使用 AuthGuards 进行重定向,您可以为选项卡级别创建一个模块并在您的模块中执行类似的操作

import { AngularFireAuthGuardModule, AngularFireAuthGuard, loggedIn, redirectUnauthorizedTo, canActivate } from '@angular/fire/auth-guard';
...
const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['tabs/login']);
...
path: 'tabs/home', loadChildren: () => import('./home/home.module').then(m => m.HomePageModule), ...canActivate(redirectUnauthorizedToLogin),
...
path: 'tabs/profile', loadChildren: () => import('./profile/profile.module').then(m => m.ProfilePageModule), ...canActivate(redirectUnauthorizedToLogin)

...

参考

angularfire 路由器防护罩


推荐阅读