Home > front end >  How to use Firestore Security Rules to let users only access their own resources
How to use Firestore Security Rules to let users only access their own resources

Time:08-24

I'm pretty new to Firebase and am trying to make a simple todo list app with different users (Mainly to get the hang of Firestore and security rules).

I've created two accounts with two different emails, as follows:

Firebase Auth Users

And this is picture of one of the documents with userID field to identify the owner. (Notice it matches one of the Auth users.

todos document with userID

I am trying to create security rules so that each user can only view their todos by checking request.auth.uid and the todo.userID as per the following screenshot:

Firebase Security Rules

The write rule is working, I tested it with different UIDs and it properly rejected the request. However, I keep getting permission-denied when trying to read the document. I tried so many different things, went through the documentation but still could not resolve this. Any idea on how to resolve this?

Thank you in advance

RESOLVED

Code before solution

const collectionRef = collection(db, "todos");

export function subscribeToDatebase(setTodos, setErr, uid) {
  function snapshot(snapshot) {
    const todosCollection = snapshot.docs;
    const todos = [];
    todosCollection.forEach((t, i) =>
      todos.push({
        firebaseID: t.id,
        ...t.data(),
        timeStamp: t.data().timeStamp,
      })
    );
    setTodos(todos);
  }

  function error(err) {
    setErr(err.code);
  }

  const unSub = onSnapshot(collectionRef, snapshot, error);
  return unSub;
}

Code after solution

const collectionRef = collection(db, "todos");

export function subscribeToDatebase(setTodos, setErr, uid) {
  function snapshot(snapshot) {
    const todosCollection = snapshot.docs;
    const todos = [];
    todosCollection.forEach((t, i) =>
      todos.push({
        firebaseID: t.id,
        ...t.data(),
        timeStamp: t.data().timeStamp,
      })
    );
    setTodos(todos);
  }

  function error(err) {
    setErr(err.code);
  }


  // This is the missing line 
  const q = query(collectionRef, where("userID", "==", uid));

  // Changing the reference to the query
  const unSub = onSnapshot(q, snapshot, error);
  return unSub;
}

CodePudding user response:

Firebase security rules don't filter data, but merely make sure that the app is only trying to read data it is allowed to read. It's hard to be certain without seeing the code that fails, but my educated guess is that you're not actually querying for uid in the read operations.

So to match with your rules, you need a query that only tries to read the user's own data, like this (in the v8 JavaScript syntax):

todosCollectionRef.where('userID', '==', firebase.auth.currentUser.uid)

Also see the documentation on query based rules

  • Related