I have the following setup ( with your knowledge , help and effort and I THANK YOU very much for this)
{
"rules": {
//".read": true,
"Users" : {
"3X3": {
".indexOn": ["time"],
".read": "data.exists()",
"$userID": {
".write": "!data.exists() || !newData.exists() || data.child('time').val() > newData.child('time').val() || data.child('userName').val() != newData.child('userName').val()"
}
}
}
}
}
I need only someone who has already a userID to be able to read the following table , no one else.
Can you please help me on this.
thank you
I tried to move the ".read": "data.exists()" below the "$userID": but it is not working meaning no data are fetched.
I am trying to give read access to posts made by a user based on the user being a friend of the author. However, Firebase tells me "variable unknown $friendId". Here are my
rules:
users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid",
"posts": {
"public": {
".read" : "auth != null"
},
"private" : {
".read": "root.child('users').child($uid).child('friends').child($friendId) === auth.id"
}
}
}
Basically, I want Firebase to check if /users/$uid/friends/ contains the friends Id and give permission to read /users/$uid/posts/private if that is the case.
Indeed, Firebase seems to be unable to accept new variables from the condition statement. However, you can just use auth.variables. All I did was change the final part about the private posts:
"private": {
".read": "root.child('users').child($uid).child('friends').child(auth.uid).exists()"
}
Set rules in Firebase console:
{
"rules": {
".read": true,
".write": true
}
}
Run in Chrome console:
> firebase.database().ref().set('foo');
Database tab of Firebase Console now reflects foo.
Set rules in Firebase console:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Run in Chrome console:
> firebase.auth().signInAnonymously()
< A {W: 1, sa: undefined, u: null, oa: null, fb: nul…}
> firebase.database().ref().set('bar');
Uncaught (in promise) Error: PERMISSION_DENIED: Permission denied
Firebase is set up to allow anonymous and Google users, both of which get PERMISSION DENIED when I attempt to read or write.
EDIT
I've added an example project here:
https://github.com/formido/react-firebaseui-web-stackoverflow-question
If I set my rules to:
{
"rules": {
".read": "auth != null",
"44358340": { ".write": true }
}
}
...and log in, the console will print Timestamp written.
If I set my rules to:
{
"rules": {
".read": "auth != null",
"44358340": { ".write": "auth != null" }
}
}
...and log in, the console will print PERMISSION DENIED.
The most relevant part of the code I'm aware of is:
componentDidMount() {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
const ref = firebase.database().ref("/44358340");
if (user) {
const timestamp = firebase.database.ServerValue.TIMESTAMP;
ref.set(timestamp).then((error) => {
if (error) {
console.error(error);
}
else {
console.log('Timestamp written');
}
});
}
}
this.setState({loading: false, user});
});
}
It's hosted on an Amazon server. I thought maybe I had to set the AUTH_DOMAIN to the AWS host, but that didn't make a difference.
It was a bug. See discussion starting here.
Fix here and it was deployed in Firebase 4.1.2.
I have a page that is calling addCheckin() method which is inside a controller. In the controller, I am trying to create a reference as follows:
var ref = firebase.database().ref("users/" + $scope.whichuser + "/meetings/" +$scope.whichmeeting + "/checkins");
$scope.whichuser and $scope.whichmeeting are the $routeParams that I am passing from another route.
Here's my checkin controller-
myApp.controller("CheckinsController",
['$scope','$rootScope','$firebaseArray','$routeParams','$firebaseObject',
function($scope,$rootScope,$firebaseArray,$routeParams,$firebaseObject){
$scope.whichuser = $routeParams.uid;
$scope.whichmeeting = $routeParams.mid;
var ref = firebase.database().ref("users/" + $scope.whichuser + "/meetings/" +$scope.whichmeeting + "/checkins");
$scope.addCheckin = function(){
var checkinInfo = $firebaseArray(ref);
var data={
firstname:$scope.firstname,
lastname:$scope.lastname,
email:$scope.email,
date:firebase.database.ServerValue.TIMESTAMP
}
checkinInfo.$add(data);
}
}]);/*controller*/
There are two errors that I am getting here-
Error 1:
Error: permission_denied at /users/Vp2P1MqKm7ckXqV2Uy3OzTnn6bB3/meetings: Client doesn't have permission to access the desired data.
Error 2:
Error: permission_denied at /users/Vp2P1MqKm7ckXqV2Uy3OzTnn6bB3/meetings/-KT5tqMYKXsFssmcRLm6/checkins: Client doesn't have permission to access the desired data.
And this is what I am tring to achieve-
Go to Firebase console of your app
Select Database From Side Menu --> Select Rule From tabs above --> Update your rule like this
{
"rules": {
".read": true,
".write": true
}
}
hope it solve your problem . thanks :)
Firebase project by default starts with Firestore as database.
This issue can happen if the application uses "Firebase Realtime Database" and permission for it are not configured. Read and write permission for Firebase Realtime Database should be explicitly granted.
To do so, in Firebase console, Database > Pick "Realtime Database" instead of "Firestore Beta" from the dropdown beside Database > Rules > Set
{
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
"rules": {
".read": true,
".write": true
}
}
Hope that help!
As all provided answers include a security issue where everyone could write / delete entries in your database, which for instance could cause extensive costs and or complete loss of data, when used in a bad way.
Of course you need to use firebase authentication features to use those rules, but preventing write access for anonymous should be default. The following rule provides read access to everyone while keeping security.
{
"rules": {
".read": true,
".write": "auth.uid != null"
}
}
None of these answers provide the most secure way to set up the Realtime Database.
You don't want anyone to randomly access or write to your database
Even if the user is authenticated, you don't want them to access other's data
This rule should address all the cases:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
Please register your self in firebase by using the below code
Firebase.auth()
.createUserWithEmailAndPassword(email, password)
.then((data) => console.log(data))
.catch(error => console.log(error))
and authenticate your self using registered email and password by below code
Firebase.auth()
.signInWithEmailAndPassword(email, password)
.then((data) => console.log(data))
.catch(error => console.log(error))
With the below rules in your real time database
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
Then automatically you will be able to access the data from the real time database
var ref = firebase.database().ref("users");
ref.on("value", function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var childData = childSnapshot.val();
var id=childData.id;
console.log(childData);
});
});
While logging out add the below command to logout of the app
Firebase.auth().signOut()
In order to grant access to all authenticated users, go to database rules tab in firebase web console and copy/paste following rules:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
It appears that the /users/{uid} routes can be written to but they can not be read from. I changed /users to /userx and it immediately began working.
I hope this can help you.
{
".read": true,
".write": "auth !== null && root.child('users').child(auth.uid).child('meetings').val() === true"
}
You can remove the string && root.child('users').child(auth.uid).child('meetings').val() === true"
and the result is the same.
You can also specify the time, till that you wanna allow like this:
Select Database From Side Menu --> Select Rule From tabs above --> Update your rule like this
{
"rules": {
".read": "now < 1672384350000", // 2022-12-30
".write": "now < 1672384350000", // 2022-12-30
}
}
If someone still get the Error: permission_denied after allowing correct read rights and are fetching data with some kind of firebase npm package; it could be because you're trying to read from Realtime Database instead of the Cloud Firestore.
I was using react-redux-firebase npm package for a quick and easy setup. By default it uses the Realtime Database. If you're using Cloud Firestore you need to state that in the config with useFirestoreForProfile set to true.
import { ReactReduxFirebaseProvider } from 'react-redux-firebase';
const store = configureStore();
const rrfProps = {
firebase,
config: {
userProfile: 'users',
useFirestoreForProfile: true // Firestore for Profile instead of Realtime DB
},
dispatch: store.dispatch,
createFirestoreInstance,
};
Probably similar issues with other packages for firebase, like flamelink that support Realtime Database but not Cloud Firestore as stated in this issue.
I'm writing an invitation application, and would like to email individual people unique URLs, e.g.
http://www.example.com/invitation.html?inviteID=-Jkbw6ycU7ZUOipmqlb5
The HTML app contains JavaScript that connects to a particular Firebase, looking up a node by the inviteID from the URL. Example:
https://my-firebase-123#firebaseio.com/-Jkbw6ycU7ZUOipmqlb5
Each top-level node looks roughly like
-Jkbw6ycU7ZUOipmqlb5: {
email: 'joe#gmail.com',
people: [
{name: 'Joe', accept: true},
{name: 'Jane', accept: false}
],
comments: 'Jane can't make it, but I'm looking forward to it!'
}
This already works great! But I'm having trouble understanding how to properly secure the data. I need the recipients to continue to be able to access those URLs without authentication - anyone who supplies a node ID can read and write to that node and its children - and yet I need to require auth to see the Firebase at its top level, so that invitees cannot see (or modify!) anyone else's responses without knowing other inviteIDs. How can I do this?
{
"rules": {
".read": ??
".write": ??
}
}
I expect both .read and .write will need a rule that means something like this:
"You requested a specific child node, not the top level node; otherwise you must be an authorized user (auth != null) to see the top level node."
The app is written in ReactJS and communicates with Firebase roughly like this:
componentWillMount: function() {
var dbAddress = 'my-firebase-123#firebaseio.com/';
this.firebaseRef = new Firebase(dbAddress + this.props.inviteId);
this.firebaseRef.on("value", function(dataSnapshot) {
this.setState(dataSnapshot.val());
}.bind(this));
},
onSend: function() {
this.firebaseRef.set(this.state);
},
I have been reading the various firebase docs trying to find a similar solution.
Assuming your firebase json structure is something like the following:
{ Invitations: {
-Jkbw6ycU7ZUOipmqlb5: {
email: 'joe#gmail.com',
people: [
{name: 'Joe', accept: true},
{name: 'Jane', accept: false}
],
comments: 'Jane can't make it, but I'm looking forward to it!'
}
-Jkbw6ycU7ZUOipmqlb6: {
... another invitation ...
}
-Jkbw6ycU7ZUOipmqlb7: {
... another invitation ...
}
}
I came up with the following security config which appears to do what you require:
{
"rules": {
".read": false,
".write": false,
"invitations": {
"$inviteid": {
".read": true,
".write": true
}
}
}
}
Actually the top level read/write false may be inferred because if I set the config as the following it seems to work in the same way:
{
"rules": {
"invitations": {
"$inviteid": {
".read": true,
".write": true
}
}
}
}
Now I cant seem to be able to browse the invitations as in if I try and mount at the following points I get permission denied (assuming your firebase address is https://my-firebase-123#firebaseio.com/:
this.firebaseRef = new Firebase('https://my-firebase-123#firebaseio.com/');
this.firebaseRef = new Firebase('https://my-firebase-123#firebaseio.com/invitations');
where as mounting at the following level lets me in:
this.firebaseRef = new Firebase('https://my-firebase-123#firebaseio.com/invitations/-Jkbw6ycU7ZUOipmqlb5');
Not sure if what I have done is actually achieving your requirements from a security perspective (i.e. is it actually secure?).
Would appreciate any feedback from the expert firebase community on this approach.