Search code examples
javascriptfirebasegoogle-cloud-firestorenext.jsfirebase-security

A user doesn't have any persmission when its account has just been created in Firebase (web version), why?


I'm trying to use Firebase in the web project (with NextJS), but here is my problem: the user doesn't have an account, so naturally the account is created with createUserWithEmailAndPassword(). However, I want to store data in Firestore right after the creation of the account... and there is the problem. Indeed Firebase throws the following error:

FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

Here is an extract of my code:

import { useState } from "react";
import {
  createUserWithEmailAndPassword,
  getAuth,
} from "firebase/auth";
import {
  collection,
  getFirestore,
  addDoc,
} from "firebase/firestore";

export const ConnectionPage = () => {
  // the values of the inputs in the HTML content
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  // the function executed when the user clicks the register button
  const submit = async (e) => {
    e.preventDefault();
    // create a new user with email and password
    // and add the document in the "users" collection
    try {
      const userCredentials = await createUserWithEmailAndPassword(
        getAuth(),
        email,
        password
      );
      const user = userCredentials.user;
      const userInfo = {
        uid: user.uid,
        // ...and all kind of data
      };
      const collectionRef = collection(getFirestore(), "users");
      // my problem starts here
      // the following line will throw an error
      // "[code=permission-denied]: Missing or insufficient permissions."
      // whereas, according to the rules in Firestore, it should work
      // because I just ask the user to be authenticated (`allow write, read: if request.auth != null`)
      // and according to the documentation, `createUserWithEmailAndPassword` logs in the user.
      const docRef = await addDoc(collectionRef, userInfo);
      console.log(`New document with id '${docRef.id}' created successfully.`);
    } catch (e) {
      console.error("An error has occured during register, look:");
      console.error(e.toString());
    }
  };

  // returns a form
  // with an email input
  // and a password input
  // and a button to register
};

Here are my rules in Firestore:

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

Please help me, the only solution I can find on a similar problem is to sign out the user after the creation of the account, and sign in right after that.

I tried:

  • in-promise syntax (.then()) but the problem is the same than with async/await
  • onAuthStateChanged(), but the same problem occurs.
  • Changing the rules to something more complex (like testing the existence of the user according to the request.auth.uid) doesn't work either.

Solution

  • the problem is fixed thanks to the contributors I talked to in GitHub. The problem was coming from the App Check feature which does not work with Firestore until the version 9.6.0.

    The solution is:

    npm install firebase@9.6.0
    

    By default, npm install firebase is installing version 9.5.0.

    Note that this version is recent and if you see that message in 2031 it's completely useless.

    Thank to the people who answered me :)