Firestore rule to read collection - javascript

Firestore rule to read collection overrides document rule to deny unauthorized access of other users data.
Here's my scenario, I'm getting the user information with the phone number associated by the Authentication and the Document in the database. I'm querying the whole /users collection with where clause and in the Firestore Rules I'm letting anyone to read /users collection, but I think this is insecure.
Javascript
const phone_number = firebase.auth().currentUser.phoneNumber // Example: "+5521988887777"
const usersRef = firebase.firestore().collection('users')
usersRef.where("phone_number", "==", phone_number).limit(1).get()
.then(snapshot => {
const doc = snapshot.docs[0]
Firestore Rules
service cloud.firestore {
match /databases/{database}/documents {
match /users {
allow read;
}
match /users/{user} {
allow read, write: if request.auth != null && request.auth.token.phone_number == resource.data.phone_number;
}
}
}
I'm trying to achieve a workaround to the issue, thanks.

To correct the security rule I have removed the first condition to allow all reads (as commented above).
Working Firestore Rules
service cloud.firestore {
match /databases/{database}/documents {
match /users/{user} {
allow read, write: if request.auth != null && request.auth.token.phone_number == resource.data.phone_number;
}
}
}

Related

Angular and firestore rules

I'm really new to Firebase and Firestore database.
I have an angular project and I use the angular/fire package to communicate with firebase.
I have created a user with user/password method and the call works perfectly.
try {
const user = await signInWithEmailAndPassword(this.auth, email, password);
return user;
} catch (e) {
return null;
}
After that I would like to store some data in the firestore db and all works fine
addVideoId(storageVideoId: StorageVideoIdModel) {
const notesRef = collection(this.firestore, 'videoIds');
return setDoc( doc(notesRef, '' + storageVideoId.date), storageVideoId );
}
After that comes the problem.
I applied a rule in the firestore console:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /videoIds/{id} {
allow read, write: if request.auth != null;
}
}
}
well... if I run the addVideoId function.... IT WORKS!
The playgroud tells me that the rule is valid and no operations are permitted, but If I run the addVideoId from angular code without log in, it works anyway....
I really don't understand how to pass that auth object in the rule...
I need some help because are 2 days that I'm stuck on it and I cannot find any example or tutorial that merge authentication with database rules.
Please help
Thanks
I think you want to define where the user has permission to write to, otherwise, your users can overwrite each other's data.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{userId}/videoIds/{id} {
allow read;
allow write: if request.auth != null && request.auth.uid == userId;
}
}
}
this will allow all users to read, but only write to their own collection.

I get a missing permissions error in firebase even though I allow it to read

I am working on a react firebase project.
the error I am getting is
"FirebaseError: Missing or insufficient permissions."
Here is my code to get the data
const data = await getDocs(
query(collectionGroup(db, "posts"), orderBy("upvote", "desc"), limit(5)));
Here is my firebase security rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{docId}{
allow read;
allow update: if request.auth.uid != null;
}
}
}
I have no idea what is going on I allow read in firebase rules but when I go and get the data it does not work
You should check if in the Database under the rules if read: true and write: true if not make those true.
So go to DataBase-> Rules
make
Read:true
Write:true
But for production databases allow only for authenticated users

How safely show publicly UID of firestore sub-collection

I have the following firestore db structure (image 1). I want (unauthenticated) users of my web app to be able to see each plumber public profile which contains reviews (image 2) they get from the won jobs. My question is how could i safely expose UID of each user who has made one of those reviews. Hopefully my question makes sense.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
the ui i want to archive
If you want to allow users to read/write their own user document and allow anyone to read their reviews, try these rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update: if request.auth.uid == userId;
match /reviews/{reviewId} {
allow read: if true;
allow write: if request.auth.uid == resource.data.userId
}
}
}
}
Here only the poster of review and write (update/delete) it and any unauthenticated users can read them. However they cannot access the User document.
You can read more about security rules in the documentation.

how to set permissions in firebase firestore

$path = "firebase_auth.json";
$config = array(
"projectId" => "XXXX",
"keyFile" => json_decode(file_get_contents($path), true)
);
$firestore = new FirestoreClient($config);
$collectionReference = $firestore->collection('Channels');
$snapshot = $collectionReference->documents().get();
Response of this code is
An uncaught Exception was encountered
Type: Google\Cloud\Core\Exception\ServiceException
Message: { "message": "Missing or insufficient permissions.", "code": 7, "status": "PERMISSION_DENIED", "details": [] }
Filename: /var/www/html/riglynx/vendor/google/cloud/Core/src/GrpcRequestWrapper.php
Line Number: 263
check out Get started with Cloud Firestore Security Rules documentation. And see Writing conditions for Cloud Firestore Security Rules documentation.
One of the most common security rule patterns is controlling access
based on the user's authentication state. For example, your app may
want to allow only signed-in users to write data:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to access documents in the "cities" collection
// only if they are authenticated.
match /cities/{city} {
allow read, write: if request.auth.uid != null;
}
}
}
This should help you get started.
Reason you are getting the error is because you are not allowed to access documents of the collection called Channels.
In order to fix this, you have login to your console firebase.
Navigate to Database > Under firestore database, you have to click on Rules.
Under rules, you can give permission as per your wish.
If you want to give access to al the users then you can simple replace current code with the following code. (Not a good practice and not secure too)
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}

Cloud Firestore with Authentication

I have been looking for a way to use Authentication with Firebase's new Cloud Firestore. I know it's possible, but there is no good guide both in the Documentation and other places.
Could someone please explain how to provide an Authentication UID when get()ing data from Cloud Firestore?
Here are my security rules:
service cloud.firestore {
match /users/{userID} {
allow read, write: if request.auth.uid == userID;
}
}
And here is my current code:
var db = firebase.firestore();
var docRef = db.collection("users").doc(uid); //lets say "uid" var is already defined
docRef.get().then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
The structure of my database is just a "users" collection at root, then a document for each user (named after the UID). I want to get the document with the user's UID.
Of course, this gives the error "Missing or insufficient permissions," which is expected, because of the security rules.
This question may seem simple, but if anyone can find some good documentation on this, that would be great!
I was just confused about how UIDs work. I was under the impression that you have to supply a UID and an auth token to database operation.
You don't actually pass in a UID to database operations. The firebase object stores authentication state. You can simply sign in (check the Firebase docs to read how to do this), and after the action is completed (use a .then promise statement) you can simply do your operation.
Additionally, to have users not sign in every time they visit your app, you can have the `firebase object's authentication state persistent.
Your rule should be inside match /databases/{database}/documents
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userID} {
allow read, write: if request.auth.uid == userID;
}
}
}

Categories

Resources