为什么用户'始终是null'在Onauthstatatechanged中(firebase 9+ vue 3+ pinia)?
我对firebase的onauthstatatechanged
有问题,无论我尝试过什么,我始终将用户
作为null
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.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)();
};
I have a problem with Firebase's onAuthStateChanged
which no matter what I've tried always returns the user
as null
after page reload. The required behavior is to auto-login user after page reload.
That is the first time I use the modular version of Firebase 9 and Pinia as a store.
I've already tried to use setPersistence
(LOCAL) but the result is the same.
I'm stuck for the whole day and cannot figure out why it's not working.
I'd be grateful for pointing out what I'm missing there.
Packages I use in my package.json
:
"dependencies": {
"firebase": "^9.6.11",
"pinia": "^2.0.13",
"vue": "^3.2.13",
"vue-router": "^4.0.3"
}
main.ts
file:
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
file:
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
-> store file:
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)();
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于通过将
持久性
选项添加到initializeauth
来解决此问题。 and 文档应该如何使用initializeauth
方法...,应在
firebase.ts.ts
文件中初始化。这是
auth
的方式 've在 docs :这就是我在
auth-public.d.ts
文件中发现的内容:和
inmemorypersistence
nocenone
持久性。那是我问题的原因。I've finally solved this problem by adding
persistence
option toinitializeAuth
. And documentation for this part is misleading and does not explain properly how it should be done withinitializeAuth
method...This is how
auth
should be initialized infirebase.ts
file:It is interesting what I've found in docs:
And this is what I've found in
auth-public.d.ts
file:And
inMemoryPersistence
meansNONE
persistence. And that was cause of my problem.