У пользователя нет никаких полномочий, когда его учетная запись только что была создана в Firebase (веб-версия), почему?

#javascript #firebase #google-cloud-firestore #next.js #firebase-security

#javascript #огневая база #google-cloud-firestore #next.js #firebase-безопасность

Вопрос:

Я пытаюсь использовать Firebase в веб-проекте (с NextJS), но вот в чем моя проблема: у пользователя нет учетной записи, поэтому, естественно, учетная запись создается с createUserWithEmailAndPassword() помощью . Однако я хочу сохранить данные в Firestore сразу после создания учетной записи… и вот в чем проблема. Действительно, Firebase выдает следующую ошибку:

Ошибка FirebaseError: [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
};
 

Вот мои правила в Firestore:

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

Пожалуйста, помогите мне, единственное решение, которое я могу найти для решения подобной проблемы, — это выйти из системы пользователя после создания учетной записи и сразу после этого войти в систему.

Я пытался:

  • синтаксис in-promise ( .then() ), но проблема та же, что и с async/await
  • onAuthStateChanged() , но возникает та же проблема.
  • Изменение правил на что-то более сложное (например, проверка существования пользователя в соответствии с request.auth.uid ) также не работает.

Комментарии:

1. Код collection(getFirestore(), "users") никогда не должен завершаться сбоем, потому что он никогда не обращается к службе и не требует никаких разрешений. Это просто создание ссылки на коллекцию. Это продолжается до следующей строки кода, в которой вы вызываете addDoc , что что-то происходит в Firestore.

2. Хорошо, я отредактирую вопрос

Ответ №1:

Когда у вас просто есть:

 allow read;
 

Это целая инструкция, и это означает, что никто не может прочитать данные.

Если вы хотите применить одно и то же условие как для чтения, так и для записи, используйте:

 allow read, write: if request.auth != null;
 

Комментарии:

1. У меня все та же ошибка; (Моя цель — получить это разрешение при создании учетной записи

Ответ №2:

Попробуйте использовать auth state observer вместо простого await создания учетной записи. По моему опыту, текущий объект user устанавливается не сразу после создания учетной записи, и вам нужно подождать, пока наблюдатель состояния аутентификации не запустится с ненулевым объектом user, чтобы иметь возможность выполнять аутентифицированные запросы. Без ненулевого CurrentUser запросы Firestore, требующие авторизации, завершатся неудачей.

 import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth();
onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    const uid = user.uid;
    // ...
  } else {
    // User is signed out
    // ...
  }
});
 

Если вам это кажется ошибкой, я предлагаю опубликовать ее на GitHub.

Комментарии:

1. Ничего не работает, по моему мнению, это определенно ненормальное поведение. Я сообщу об этом как об ошибке на GitHub

2. Когда вы говорите «ничего не работает», неплохо подкрепить это всеми вещами, которые вы на самом деле пробовали, особенно наблюдателем состояния аутентификации, который показан в документации продукта. Пожалуйста, отредактируйте вопрос, чтобы показать все, что работает не так, как вы ожидаете.

3. Хорошо, позвольте мне добавить подробности

Ответ №3:

проблема устранена благодаря авторам, с которыми я общался в GitHub. Проблема заключалась в функции проверки приложений, которая не работает с Firestore до версии 9.6.0 .

Решение таково:

 npm install firebase@9.6.0
 

По умолчанию npm install firebase устанавливается версия 9.5.0 .

Обратите внимание, что эта версия является последней, и если вы видите это сообщение в 2031 году, оно совершенно бесполезно.

Спасибо людям, которые ответили мне 🙂