-
Notifications
You must be signed in to change notification settings - Fork 422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
currentUser is null after logging in in app/page.tsx #306
Comments
Was just about to create an issue for this myself. To elaborate a bit, even with
As
|
@jamezening I ended up figuring it out. It seems like the currentUser is null because the service worker doesn't update its cached token right after the login happens. I fixed this by doing this right after the login:
My full AuthProvider.tsx code for your reference:
I put my authprovider around everything in the top level layout.tsx. Hopefully this helps. But now it works great for me @jamezening |
+1 |
I just needed to pass the token to headers. I managed to achieve this by the following: // service-worker.ts
import { type FirebaseOptions, getApps, initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getInstallations, getToken } from 'firebase/installations';
let token: Promise<string | null> | string | null;
initialize();
self.addEventListener('install', (event: any) => {
//@ts-ignore
self.skipWaiting();
});
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'UPDATE_FIREBASE_TOKEN') {
token = event.data.token;
}
});
self.addEventListener('activate', (event: any) => {
// @ts-ignore
event.waitUntil(clients.claim());
});
// @ts-expect-error This type is only in sw
self.addEventListener('fetch', (event: FetchEvent) => {
const { origin } = new URL(event.request.url);
if (origin !== self.location.origin) return;
event.respondWith(fetchWithFirebaseHeaders(event.request));
});
function initialize() {
if (!getApps().length) {
const firebaseConfig: FirebaseOptions = JSON.parse(FIREBASE_CONFIG);
if (!firebaseConfig) throw new Error('Firebase config not found');
initializeApp(firebaseConfig);
}
token = new Promise((resolve) => {
const unsubscribe = getAuth().onAuthStateChanged((user) => {
unsubscribe();
if (user) {
user.getIdToken().then(
(idToken) => {
resolve(idToken);
},
(e) => {
resolve(null);
}
);
} else {
resolve(null);
}
});
});
getAuth().onAuthStateChanged((user) => {
if (user === undefined) return;
token = new Promise((res) => {
if (!user) return res(null);
user.getIdToken().then((t) => res(t));
});
});
getAuth().onIdTokenChanged((user) => {
if (user === undefined) return;
token = new Promise((res) => {
if (!user) return res(null);
user.getIdToken().then((t) => res(t));
});
});
}
async function fetchWithFirebaseHeaders(request: Request) {
const [authIdToken, installationToken] = await Promise.all([
getAuthIdToken(),
getToken(getInstallations())
]);
const headers = new Headers(request.headers);
headers.append('Firebase-Instance-ID-Token', installationToken);
if (authIdToken) headers.append('Authorization', `Bearer ${authIdToken}`);
const newRequest = new Request(request, { headers });
return await fetch(newRequest);
}
async function getAuthIdToken() {
if (typeof token === 'object') token = await token;
return token;
} Firebase instance on the service woker doesn't update its user state immediately with the runtime instance. So I'm updating it manually after signing in or out. // common.ts
export function updateServiceWorkerToken(token: string | null) {
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage({
type: 'UPDATE_FIREBASE_TOKEN',
token
});
} else {
console.warn('Service worker not available.');
}
} Finally calling it on signIn/signOut: async signIn(token) {
const cred = await signInWithCustomToken(token)
token = await cred.user.getIdToken()
updateServiceWorkerToken(token)
goto(url)
} [It took me eternity to come up with this lol] |
I understand that page.tsx is a server rendered component, but is it possible to update currentUser somehow after a log in happens?
The flow I want:
It works after refreshing, but without refreshing, currentUser remains null. What's the best practice to deal with this?
The text was updated successfully, but these errors were encountered: