1
votes

I want to make it so I can have authenticated users write to a collection that is only read/write/create-able to that user only. I'm struggling with the most basic Firestore setup. My firestore rules look like this:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{userId} {
      allow read, write, create: if request.auth.uid == userId;
    }
  }
}

I'm assuming this will prevent read/writes/creates to the database unless the initial part of the path matches the UID of the logged in user.

My JavaScript code looks like this:

function addSomeData(data) {
    console.log( "Sending data with: ", user.uid, data );
    db.collection(user.uid).add({ data })
        .then(function(docRef) {
            console.log("Document written with ID: ", docRef.id);
        })
        .catch(function(error) {
            console.error("Error adding document: ", error);
        });
}

I definitely have user.id set correctly after successful login.

Using things this way always gives me this error in the console:

Error adding document: Error: Missing or insufficient permissions.

If I revert to the original rules like this then the document is successfully created:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}

What I'm trying to do is have each collection start with the UID of the logged in user. So, a sample shape of the data might be this:

/ax323/brty/data="Hello"
/ax323/98da/data="Goodbye"
/br981/ha31/data="No comment"

So, ax323 is a UID in Firebase, as is br981. ax323 has two documents in the collection, while br981 has one.

Is the "shape" of my data the problem?

I don't really understand what the {document=**} means in the original rules, and whether I need to convert my authentication rule to something similar.

1

1 Answers

4
votes

In your database rules you have used match /users/{userId} { This rule will apply only to the document mathching that particular path. So if your document path is /ax323/brty/data then your rules should be like

service cloud.firestore {
  match /databases/{database}/documents {
    match /{userId}/{document=**} {
      allow read, write, create: if request.auth.uid == userId;
    }
  }
}

Also looking at your question, I can't get what brty means when you mentioned

/ax323/brty/data="Hello" ?