Getting this firebase error: FirebaseError: [code=permission-denied]: Missing or insufficient permissions

Advertisements

Changed my firebase rules, to allow user data to be stored, however it did not work. I am also working with stripe. I’ve included firebase rules, my login component and initializing firebase in my app.

Every time I press signup button, I get that error in the title.

Firebase Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /customers/{uid} {
      allow read, write: if request.auth.uid == uid;

      match /checkout_sessions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
      match /subscriptions/{id} {
        allow read: if request.auth.uid == uid;
      }
      match /payments/{id} {
        allow read: if request.auth.uid == uid;
      }
      match /users/{userId} {
  allow read, write: if request.auth.uid == userId;
}

    }

    match /products/{id} {
      allow read: if true;

      match /prices/{id} {
        allow read: if true;
      }

      match /tax_rates/{id} {
        allow read: if true;
      }

    }
  }
}

Login component:

import {
  closeLoginModal,
  closePasswordModal,
  closeSignupModal,
  openLoginModal,
  openPasswordModal,
  openSignupModal,
} from "@/redux/modalSlice";
import { faUser, faXmark } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Modal from "@mui/material/Modal";
import { useDispatch, useSelector } from "react-redux";
import {
  browserLocalPersistence,
  createUserWithEmailAndPassword,
  onAuthStateChanged,
  setPersistence,
  signInWithEmailAndPassword,
} from "firebase/auth";
import { db } from "@/firebase";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { getAuth, GoogleAuthProvider, signInWithPopup } from "firebase/auth";
import { app } from "@/firebase";
import { doc, setDoc } from "firebase/firestore";

export default function LoginModal() {
  // Modal
  const isLoginOpen = useSelector((state) => state.modals.loginModalOpen);
  const isSignupOpen = useSelector((state) => state.modals.signupModalOpen);
  const isPasswordOpen = useSelector((state) => state.modals.passwordModalOpen);

  // Firebase
  const auth = getAuth();
  const provider = new GoogleAuthProvider();

  const dispatch = useDispatch();
  const router = useRouter();

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [loginError, setLoginError] = useState("");

  const handleSignup = async (e) => {
    e.preventDefault();
    console.log("called");
    console.log(email);
    try {
      console.log("success");
      await setPersistence(auth, browserLocalPersistence);
      const userCredentials = await createUserWithEmailAndPassword(
        auth,
        email,
        password
      );
      // await createUserWithEmailAndPassword(auth, email, password);
      const user = userCredentials.user;
      console.log(user);
      if (user) {
        await setDoc(doc(db, "users", user.uid), {
          email: user.email,
          uid: user.uid,
        });
        setLoginError("");
        console.log("loggedIn");
        goToForYouPage();
      }
    } catch (error) {
      setLoginError("Wrong email or password. Please try again.");
      alert(error);
      console.error("error", error);
    }
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      await setPersistence(auth, browserLocalPersistence);
      // await signInWithEmailAndPassword(auth, email, password);
      const userCredentials = await signInWithEmailAndPassword(
        auth,
        email,
        password
      );
      const user = userCredentials.user;
      if (user) {
        await setDoc(doc(db, "users", user.uid), {
          email: user.email,
          uid: user.uid,
        });
        setLoginError("");
        console.log("loggedIn");
        goToForYouPage();
      }
    } catch (error) {
      setLoginError("Wrong email or password. Please try again.");
      alert(error);
    }
  };

  const handleGoogleLogin = async () => {
    const result = await signInWithPopup(auth, provider);
    const user = result.user;
    if (user) {
      goToForYouPage();
    }
  };

  const handleGuestLogin = async () => {
    e.preventDefault();
    try {
      await setPersistence(auth, browserLocalPersistence);
      const userCredentials = await signInWithEmailAndPassword(
        auth,
        "guestuser@guest.com",
        "123456"
      );
      const user = userCredentials.user;
      if (user) {
        await setDoc(doc(db, "users", user.uid), {
          email: user.email,
          uid: user.uid,
        });
      }
      goToForYouPage();
    } catch (error) {
      setLoginError("Wrong email or password. Please try again");
      alert(error);
    }
  };

  const goToForYouPage = () => {
    router.push("/for-you");
  };

  // useEffect(() => {
  //   const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
  //     console.log(currentUser);
  //   });

  //   // Make sure to unsubscribe when the component unmounts
  //   return unsubscribe;
  // }, []);

  return (
    <>
      JSX
    </>
  );
}

Firebase setup:

import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);

export { db, auth };

>Solution :

You have this operation to write to Firestore:

await setDoc(doc(db, "users", user.uid), {
  email: user.email,
  uid: user.uid,
});

So this writes a document with the current use’s UID to a top-level collection named users.

If we look at your security rules however, the only place where you grant access to a users collection is nested under a collection called customers.

To allow writing to the top-level users collection, pull up that rule or create a new top-level match /users/{userId} rule similar to the ones you already have for customers, products, prices and tax_rates.

Leave a ReplyCancel reply