为什么我的 Ngrx signalStore 在服务内更新其状态,但无法反映组件中的这些更改?

问题描述 投票:0回答:1

我正在存储在信号存储中的服务中检索到的 Firebase 身份验证详细信息,主要在这个阶段仅用于身份验证防护。

但是,虽然经过身份验证的用户似乎已从服务正确返回并在商店中更新,但商店并未在我的身份验证防护或组件中为我提供用户值。

"@angular/core": "^18.2.0",
"@angular/fire": "^18.0.1",
"@ngrx/signals": "^18.1.1",

这是我定义 signalStore 的方式:

import { User } from '@angular/fire/auth';
import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';

type AuthState = {
  user: User | null;
};

const initialState: AuthState = {
  user: null,
};

export const AuthStore = signalStore(
  { providedIn: 'root' },
  withState(initialState),
  withMethods((store) => ({
    updateUser(user: User | null): void {
      patchState(store, () => ({ user }));
    },
  }))
);

又好又简单。

我有一个 Firebase 服务,可以执行登录和监听身份验证状态等操作:

import { inject, Injectable } from '@angular/core';
import {
  getAuth,
  onAuthStateChanged,
  signInWithEmailAndPassword,
} from '@angular/fire/auth';
import { AuthStore } from '../components/auth/auth-store';

@Injectable({ providedIn: 'root' })
export class FirebaseService {
  authStore = inject(AuthStore);

  auth = getAuth();

  logIn(email: string, password: string) {
    signInWithEmailAndPassword(this.auth, email, password)
      .then((userCredential) => {
        const user = userCredential.user;
        this.authStore.updateUser(user);
      })
      .catch((error) => {
        console.log(error);
      });
  }

  constructor() {
    this.authStatusListener();
  }

  authStatusListener() {
    onAuthStateChanged(this.auth, (user) => {
      console.log('authStateChanged');
      if (user) {
        console.log(user); // logs the user data
        this.authStore.updateUser(user);
        console.log('User is logged in');
        console.log(this.authStore.user()); // logs the user data
      } else {
        this.authStore.updateUser(user);
        console.log('User is logged out');
      }
    });
  }
}

这似乎运作良好。我在那里评论的日志在没有问题的情况下进行身份验证时会注销我的测试用户。

但是,当我在我的身份验证防护中使用它时:

import { inject } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivateFn,
  Router,
  RouterStateSnapshot,
} from '@angular/router';
import { AuthStore } from './components/auth/auth-store';

export const AuthGuard: CanActivateFn = (
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => {
  const router = inject(Router);
  const authStore = inject(AuthStore);
  if (!authStore.user()) {
    console.log(authStore.user()); // null every time!
    router.navigate(['login']);
    return false;
  }
  if (authStore.user()) {
    console.log('user is authed: ', authStore.user());
    return true;
  }

  console.log('fallthrough');
  return false;
};

user() 始终为空。

即使我只是将 user() 推入登录模板中,它也是空的:

import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { FirebaseService } from '../../service/firebase.service';
import { CommonModule } from '@angular/common';
import { AuthStore } from './auth-store';

@Component({
  selector: 'app-auth',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: ` <div class="">
    <div class="">
      <h1 class="">Log In</h1>
      <div>
        <label>Email</label>
        <input
          [(ngModel)]="email"
          class=""
          type="email"
          placeholder="Your email"
        />
      </div>
      <div>
        <label>Password</label>
        <input
          [(ngModel)]="password"
          class=""
          type="password"
          placeholder="Password"
        />
      </div>
      <div>
        <button
          (click)="onSubmit()"
          type="submit"
          class=""
          [disabled]="loading"
        >
          {{ loading ? 'Loading' : 'Log In' }}
        </button>
      </div>
      <div>{{ store.user() ?? 'null' }}</div> // this here is always null
    </div>
  </div>`,
  imports: [CommonModule, FormsModule],
  providers: [AuthStore],
})
export class AuthComponent {
  loading = false;
  public store = inject(AuthStore);
  public email: string | null = null;
  public password: string | null = null;

  firebaseService = inject(FirebaseService);

  constructor(private readonly router: Router) {}

  async onSubmit(): Promise<void> {
    if (this.email && this.password) {
      this.firebaseService.logIn(this.email, this.password);
    }
  }
}

这是在我看到控制台中的日志告诉我我有一个经过身份验证的用户并将该用户打印出来之后。

所以...卡住了。这是一个范围的事情吗? DI 的东西?异步的东西?帮忙!

angular firebase-authentication ngrx-signal-store
1个回答
0
投票

你找到解决办法了吗? 我想这可能是你的错误? patchState(商店, () => ({ 用户 })); 应该是 patchState(商店, { 用户 });

© www.soinside.com 2019 - 2024. All rights reserved.