how to set permissions in firebase firestore - javascript

$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;
}
}
}

Related

How to pass Auth token in FireStore in Web app

I have developed a single crud project(Login screen and crud operation screen HTML) and hosted on firebase hosting. where User signing with email and password, I am using firebase signing with email and password and its working as expected.
But now issue is I want to secure backend with auth but its not passing auth in setDoc() deleteDoc() etc, My requirement is without auth. no one should do any operation on database.
import { doc, setDoc } from "firebase/firestore";
await setDoc(doc(db, "cities", "LA"), {
name: "Los Angeles",
state: "CA",
country: "USA"
});
below rules are working but its not secured for production env. :
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true
}
}
}
If set rules like below it give me insufficient permission error. I don't know how to pass UID in setDoc() or any operation.
allow read, write: if request.auth != null
Update : If i put below code before setDoc() below code is not executing because currentUser has user data.
function addCity(){
if (!firebase.auth().currentUser) {
// this code not executing because user is signed
alert("Login required");
window.href = "login.html";
return;
}
// i can print UID and it is showing means user is logged.
await setDoc(doc(db, "cities", "LA"), {
name: "Los Angeles",
state: "CA",
country: "USA"
});
}
This is in detail covered in the Firebase documentation on Security & Rules, which I would recommend you to check out.You can secure your data with Security Rules,Firebase Security Rules are evaluated and based on that the rules language it is validated whether the current user can access your data.
Security Rules give you access to a set of server variables to check your rules against. The most commonly used one is the auth variable which lets you check against the currently authenticated user. You can also create wildcard variables with the $, which acts as a route parameter creating.
{ "rules": { "users": { // users can read and write their own data, but no one else. "$uid": { ".read": "auth.uid == $uid", ".write": "auth.uid == $uid" } } } }
You can also check the feature called Firebase App Check, it will let you limit access to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You can combine this with the user authentication based security described above, so that you have another shield.
Also check these similar examples below:
How to prevent unauthorized access to Firebase database
How to prevent users from changing the Database data
Allow only authenticated users to modify database data
Finally,
I found solution. I was using different version library of firebase. like I was using web v8 library for login and modular lib for database access. I just moved all firebase SDK to same version and modular.

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

Firestore rule to read collection

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;
}
}
}

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