我对Firebase的onAuthStateChanged
有一个问题,不管我尝试了什么,在页面重新加载后总是将user
作为null
返回。所需的行为是在页面重新加载后自动登录用户.
这是我第一次使用Firebase 9和Pinia的模块化版本作为商店。
我已经尝试过使用setPersistence
(本地),但是结果是一样的。
我被困了一整天,弄不明白为什么不起作用。
我很感激能指出我在那里错过了什么。
我在package.json
中使用的软件包
"dependencies": {
"firebase": "^9.6.11",
"pinia": "^2.0.13",
"vue": "^3.2.13",
"vue-router": "^4.0.3"
}
main.ts
文件:
import { createApp, App as VueApp } from 'vue';
import { createPinia } from 'pinia';
import { auth } from '@/firebase';
import { onAuthStateChanged, User } from 'firebase/auth';
import { useAuthStore } from '@/store/auth';
let app: VueApp;
function initializeApp(user: User | null) {
app = createApp(App)
.use(createPinia())
.use(router);
if (user) {
// PROMEM IS THERE -> user IS ALWAYS null
// I want to set logged user before app is mounted
const authStore = useAuthStore();
authStore.handleAuthStateChange(user);
}
app.mount('#app');
}
onAuthStateChanged(
auth,
(user: User | null) => {
// PROMEM IS THERE -> user IS ALWAYS null
if (!app) {
initializeApp(user);
} else {
const authStore = useAuthStore();
authStore.handleAuthStateChange(user);
}
},
(error: Error) => {
log.error(`Main AuthStateChange handler failed with error`, error);
},
);
firebase.ts
文件:
import { FirebaseApp, initializeApp } from 'firebase/app';
import { Auth, initializeAuth, debugErrorMap } from 'firebase/auth';
import { firebaseConfig } from '@/config';
export const app: FirebaseApp = initializeApp(firebaseConfig);
export const auth: Auth = initializeAuth(app, { errorMap: debugErrorMap });
auth.ts
->存储文件:
import { defineStore } from 'pinia';
import { LoginCredentials, SignUpCredentials } from '@/types/auth';
import { FirebaseAuthenticationService, AuthenticationService } from '@/service/AuthenticationService';
import { auth as firebaseAuth } from '@/firebase';
import { log } from '@/service/LoggerService';
export interface AuthStoreUser {
uid: string,
email: string | null
}
export type MaybeAuthStoreUser = AuthStoreUser | null;
export interface AuthStoreState {
user: AuthStoreUser | null,
}
export const authStoreFactory = ($auth: AuthenticationService) => defineStore('auth', {
state: () => ({
user: null,
} as AuthStoreState),
getters: {
isUserLoggedIn(): boolean {
return !!this.user;
},
},
actions: {
async signUpUser(credentials: SignUpCredentials) {
const createdUser = await $auth.createUserWithEmailAndPassword(credentials);
},
async loginUser(credentials: LoginCredentials) {
const user = await $auth.signInWithEmailAndPassword(credentials);
},
async setCurrentUser(user: AuthStoreUser) {
this.user = user;
},
async clearCurrentUser() {
this.user = null;
},
async logoutUser() {
await $auth.signOut();
},
async sendPasswordResetEmail(email: string) {
await $auth.sendPasswordResetEmail(email);
},
async handleAuthStateChange(user: MaybeAuthStoreUser) {
if (user) {
log.debug(`Logging in user from authStateChange handler`);
this.setCurrentUser(user);
} else {
log.debug(`AuthStateChange handler did not receive current user.`);
this.clearCurrentUser();
}
},
},
});
export const useAuthStore = () => {
const $auth = new FirebaseAuthenticationService(firebaseAuth);
return authStoreFactory($auth)();
};
发布于 2022-04-23 15:53:44
通过向persistence
添加initializeAuth
选项,我终于解决了这个问题。对于这一部分,文档是误导性的,没有正确地解释如何用initializeAuth
方法来实现。
这就是如何在auth
文件中初始化firebase.ts
:
import { firebaseConfig } from '@/config';
import { FirebaseApp, initializeApp } from 'firebase/app';
import {
Auth,
initializeAuth,
debugErrorMap,
indexedDBLocalPersistence,
browserLocalPersistence } from 'firebase/auth';
export const app: FirebaseApp = initializeApp(firebaseConfig);
export const auth: Auth = initializeAuth(app, {
persistence: [indexedDBLocalPersistence, browserLocalPersistence],
errorMap: debugErrorMap
});
我在文档中发现的东西很有趣
默认的网页浏览器和反应本地应用程序是本地(只要浏览器支持这种存储机制,例如。第三方cookie/数据已启用),而Node.js后端应用程序则不启用。
这就是我在auth-public.d.ts
文件中发现的:
export declare interface Dependencies {
/**
* Which {@link Persistence} to use. If this is an array, the first
* `Persistence` that the device supports is used. The SDK searches for an
* existing account in order and, if one is found in a secondary
* `Persistence`, the account is moved to the primary `Persistence`.
*
* If no persistence is provided, the SDK falls back on
* {@link inMemoryPersistence}.
*/
persistence?: Persistence | Persistence[];
// other stuff
}
如果不提供持久性,则 SDK将回到inMemoryPersistence上。
inMemoryPersistence
意味着NONE
持久化。那是我问题的原因。
https://stackoverflow.com/questions/71979761
复制相似问题