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 have been dealing with the authorization in Firebase for two days now and I can't get it to work. Plenty of reading in the documentation and here in stackoverflow and still don't get it. This is how my rules look like...
{
"rules": {
".read": false,
".write": false,
"notes": {
".read": "auth != null",
".write": "auth != null",
".indexOn": "uid"
}
}
}
My data looks like this...
user-notes-very-upper-root
|_notes
|_-ugly_id_for_this_record
| |--date: "Sat Sep 02 2017"
| |--note: "new note from me"
| |__uid: "firebase_ugly_id"
|_-ugly_id_for_this_record
Like I said before, I can write but I can't read. I'm utilizing angularjs 1.6.6 for this. I have a firebase onAuthStateChange in the .run part to listen for authentication changes and I'm able to move arround the app the user obj. My angular code looks like this...
angular.module('userNotes').run(function($rootScope, $window) {
$rootScope.currentUser = null;
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$rootScope.currentUser = user.uid;
console.log('User logged in from Run: ', user);
} else {
$rootScope.currentUser = null;
console.warn('User logged out from Run: ', user);
$window.location.href = '#!/';
}
});
});
If I change the .read and .write rules that are right after the rules node to true I have no problem reading the data but I don't want that. I want to read data for just authenticated users.
How I can tweak the rules to make just authenticated users to read and write data.
Update Sept 4, 2017
I change the rules to...
{
"rules": {
"notes": {
".read": "auth != null",
".write": "auth != null",
".indexOn": "uid"
}
}
}
These rules don't fix the problem. I'm able to write but not to read. This is the error in the console...
Possibly unhandled rejection: {"data":{"error":"Permission denied"},"status":401
From the Understanding Firebase Realtime Database Rules documentation (emphasis mine),
.read and .write rules cascade, so this ruleset grants read access to any data at path /foo/ as well as any deeper paths such as /foo/bar/baz. Note that .read and .write rules shallower in the database override deeper rules, so read access to /foo/bar/baz would still be granted in this example even if a rule at the path /foo/bar/baz evaluated to false.
You are not able to read because you have ".read": false, which overrides the .read rule inside "notes". This does not explain though why you are still able to write when you shouldn't be because of ".write": false.
Anyway, try removing the ".read": false and ".write": false so that it does not override the rules under "notes".
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.
Inside my web-app, Firebase always tells me permission denied while things are working fine in the simulator.
FIREBASE WARNING: set at /users/simplelogin:14 failed: permission_denied
I'm having trouble adding metadata (such as a name) when users register. data is simply a JSON object that contains a name property.
var signup = function (email, password, data) {
firebaseAuth
.$createUser(email, password)
.then(function (user) {
dataRef.child('users').child(user.uid)
.set(data);
}, function (err) {
console.error(err);
});
};
My firebase rules:
{
"rules": {
"users": {
"$user": {
".read": "$user == auth.uid",
".write": "$user == auth.uid"
}
}
}
}
Simulator works fine:
Attempt to write {"name":"Test"} to /users/simplelogin:7 with auth={"uid":"simplelogin:7"}
/
/users
/users/simplelogin:7:.write: "$user == auth.uid"
=> true
Write was allowed.
As #Kato pointed out you need to log the user in yourself after registration before you can do anything.
Firebase createUser docs