Closed Henex1 closed 4 months ago
Hey @Henex1!
Client-side firestore
requires to be called in authenticated environment.
You are using setPersistence(auth, inMemoryPersistence);
as in starter example, which causes firebase client authentication to reset on page refresh.
You basically have two options here:
You remove setPersistence(auth, inMemoryPersistence);
and keep both server and client session active. You will have to keep those two session synchronised, otherwise you will run into consistency issues
You can use signInWithCustomToken
from firebase/auth
before you use client-side firestore. You can pass server token to signInWithCustomToken
and it should enable authenticated firebase environment until next page refresh
See https://firebase.google.com/docs/auth/web/custom-auth#authenticate-with-firebase for more information on how to use signInWithCustomToken
Please can you give me a sample code using the first option. I am still confused
This one is still not working.
"use client";
import { getFirebaseApp, getFirebaseAuth } from "../../lib/utils/auth/Firebase";
import { doc, getDoc, getFirestore } from "firebase/firestore";
import { useAuth } from "@/authContext/AuthContext";
import { signInWithCustomToken } from "firebase/auth";
const AuthUser = () => {
const { user }: any = useAuth();
if (!user) {
return <>Loading</>;
}
console.log(user)
const auth = getFirebaseAuth();
const dataFetecher = async () => {
try {
const { user: authUser } = await signInWithCustomToken(
auth,
user.customToken
);
// Signed in
// Handle the signed-in user information
const db = getFirestore(getFirebaseApp());
const docRef = doc(db, "umu-uzongwa-members", authUser.uid);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
// docSnap.data() will be undefined in this case
console.log("No such document!");
}
} catch (error) {
// const errorCode = (error as { code: string }).code;
const errorMessage = (error as { message: string }).message;
// Handle the error
console.log(errorMessage);
}
};
dataFetecher();
return (
<main>
<div className="flex items-center">
<h1 className="text-lg font-semibold md:text-2xl text-red-500">
Data information, please check
</h1>
</div>
</main>
);
};
export default AuthUser;
Hey, I just tested signInWithCustomToken
and can confirm that it does not work with server token. I am investigating the issue and will get back to you shortly
In the meantime, you can just remove following lines to make firestore work on the client-side:
// App relies only on server token. We make sure Firebase does not store credentials in the browser.
// See: https://github.com/awinogrodzki/next-firebase-auth-edge/issues/143
setPersistence(auth, inMemoryPersistence);
I created a pull-request that exposes customToken
in handleValidToken
and getTokens
. This customToken
can be used together with signInWithCustomToken
to authenticate Firebase Client-side SDKs.
https://github.com/awinogrodzki/next-firebase-auth-edge/pull/206
I will be releasing canary version with those changes soon. I'll keep you updated within this issue.
Thank you so much for your effort, I have updated the npm version to 1.5.3. I have removed this line
setPersistence(auth, inMemoryPersistence);
But I am still getting this error from the console on the browser.
Cannot read properties of undefined (reading 'customToken') AuthUser.tsx: undefined
Is there anything I am suppose to modify on the middleware?
I think you are getting this error by trying to access user.customToken
value and user
is undefined in this case
@Henex1 you can now install next-firebase-auth-edge@v1.6.0-canary.7
In this version, getTokens
and handleValidToken
exposes customToken
string, which you can use together with signInWithCustomToken
Ok @awinogrodzki please any code sample on how to use it to read data from firebase firestore client db? Thank you so much.
Hey @Vicidevs @Henex1! Thank you for you patience.
I have improved starter example and added Firestore Client SDK code that updates user counters
collection
Here's the function where we call signInWithCustomToken
and Firestore Client SDK methods: https://github.com/awinogrodzki/next-firebase-auth-edge/blob/main/examples/next-typescript-starter/app/profile/UserProfile/user-counters.ts
Don't forget to pass custom token to user object, as in here: https://github.com/awinogrodzki/next-firebase-auth-edge/blob/main/examples/next-typescript-starter/app/shared/user.ts#L28
In case you plan to setup starter example, please remember to setup Firestore Database rules as mentioned in starter readme: https://github.com/awinogrodzki/next-firebase-auth-edge/tree/main/examples/next-typescript-starter#configuring-firestore-rules
I also added documentation on how to use client-side APIs: https://next-firebase-auth-edge-docs.vercel.app/docs/usage/client-side-apis#using-firebase-client-sdks
Please make sure to upgrade to next-firebase-auth-edge@1.6.0
Also, please note that with the introduction of custom token, the size of authorization cookie has increased twice in size, so if you use custom claims, it's recommended to set enableMultipleCookies
to true
, unless you're using Firebase Hosting: https://next-firebase-auth-edge-docs.vercel.app/docs/usage/middleware#multiple-cookies