So i want to integrate a stripe subscription to my project. I'm using firebase 9 and next-auth(I login only with google provider for now.)Since google provider with next-auth return only 3 data(name, email and image), i add a callback to [..nextauth.ts] file to get more data like sub since i can't get the UID(like this ).
export const authOptions = {
// Configure one or more authentication providers
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID!,
clientSecret: process.env.GOOGLE_SECRET!,
}),
// ...add more providers here
],
callbacks: {
async session({ session, token, user }: any) {
session.user.token = token;
return session;
},
},
};
export default NextAuth(authOptions);
{
And it's ok, it worked..I got the token object(see below )
{
user: {
name: 'Lionel messi',
email: 'random@gmail.com',
image: 'https:/.googleusercontent.com/z/Arandom',
token: {
name: 'Lionel messi',
email: 'random@gmail.com',
picture: 'https:/.googleusercontent.com/z/Arandom',
sub: '111random57437563475920',
iat: "random",
exp: "random",
jti: 'c17388fc-dde4-4d9d-aadc-random'
}
}
}
But the sub data doesn’t seem to work with firebase/stripe security rules(I tried this ) I replaced the "uid" with "request.auth.token.sub" to get the sub from the token and get this error on the website each time i tried to subscribe : "There is no user record corresponding to the provided identifier."
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow write, read: if true
allow write: if request.auth !=null && request.auth.uid == ""
}
match /customers/request.auth.token.sub {
allow read: if request.auth.uid == request.auth.token.sub
match /checkout_sessions/{id} {
allow read, write: if request.auth.uid == request.auth.token.sub;
}
match /subscriptions/{id} {
allow read: if request.auth.uid == request.auth.token.sub;
}
match /payments/{id} {
allow read: if request.auth.uid == request.auth.token.sub;
}
}
match /products/{id} {
allow read: if true;
match /prices/{id} {
allow read: if true;
}
match /tax_rates/{id} {
allow read: if true;
}
}
}
}
Here is my loadCheckout function:
const loadCheckout = async (priceId: string) => {
// @ts-ignore
const uid = session?.user?.token?.sub;
console.log(uid, "user ID");
const payRef = await addDoc(
collection(db, `customers/${uid}/checkout_sessions`),
{
price: priceId,
success_url: window.location.origin,
cancel_url: window.location.origin,
}
);
And i called it like this : onClick={() => loadCheckout(productData?.prices?.priceId)}
I have to mention here that I am able to get the productData.prices.PriceId data(this is not the problem).
I'm sure that the error is somewhere in the security rules or the sub data is not taken properly..
Do you you guys have suggestions on how to fix this mess and go through the checkout ? or there is any other way to get the UID with a callback ?
Can i get the UID directly ? what is the proper way to get the sub in the rules ?
See above for more information