Swift + Firebase Security Not Working

Swift + Firebase Security not working

Firebase document is wrong (for now). In Firebase console, open rule simulator. There is no 'password' option at this time, I think its a bug.

If you have not use multiple authentication or multiple authentication does not matter in your project, dont use provider at your rules. Otherwise you can test this rule for password authentication:

".write": "auth != null && auth.uid === $user_id && auth.token.firebase.identities.email !== null"

Why is the firebase security rules not working?

In my opinion the problem was this:

I was accessing Firebase using this method, it is not the basic method of reading firebase service data

let baseUrl = Constants.baseUrl + ".JSON"
// where baseUrl is just http path to my database and if you add ".JSON" to it - you
// open the contents of the database in Json
guard let url = URL(string: baseUrl ) else { return }
URLSession.shared.dataTask(with: url) {data, response, error in

Then I used the given Data to parse through the model:

let jsonString = String(data: data, encoding: .utf8),
let downloadedDataAsModel = Mapper<CatalogueParts>().mapArray(JSONString: jsonString)

The problem is that using this method, regardless of the rules - you get the data in any case, while the ObjectMapper processes and creates an instance, but it is incomplete, and no error occurs here

let downloadedDataAsModel = Mapper<CatalogueParts>().mapArray (JSONString: jsonString)

Therefore, this method does not allow rule settings other than "read : true"

I tried using this method and everything really worked - depending on the authorized status, access was allowed or restricted. Now it remains to decide how to use this method to get data in the form of Json for further processing =)

func fetchData(){
let ref = Constants.ref
ref.child("CatalogueParts").getData { error, snapshot in
guard error == nil else {
print(error!.localizedDescription)
return;
}
let someValue = snapshot.value
print(someValue)
}
}

Firebase indexOn security & rules not working

You're trying to add an index on an array, which is not possible in Firebase.

As the error message tells you (it's surprisingly accurate), you need to add an index for members/rsenov:

{
"rules": {
".read": true,
".write": true,
"groups": {
"$group_id": {
".indexOn": "members/rsenov"
}
}
}
}

But this means you'll need to add an index for each user, which is very inefficient. That's why denormalization is recommended.

As an alternative (that I recommended in answer to your last question) you can create an customized index yourself, a process known as denormalizing.

{
"groups" : {
"-KB422VV21cPzpgi1wF1" : {
"author" : "rsenov",
"members" : {
"rsenov" : true
},
"name" : "Item 1"
},
"-KB423lni1Iptn2fGwi1" : {
"author" : "rsenov",
"members" : {
"rsenov" : true
},
"name" : "Item 2"
}
},
"users": {
"rsenov": {
"groups": {
"-KB422VV21cPzpgi1wF1": true,
"-KB423lni1Iptn2fGwi1": true
}
}
}
}

With this data structure, you can look up the groups for a user without even needing a query:

ref.childByAppendingPath("users/rsenov/groups")
.observeEventType(.Value, withBlock: { snapshot in

Or if you want to use the currently authenticated user:

ref.childByAppendingPath("users")
.childByAppendingPath(ref.authData.uid)
.childByAppendingPath("groups")
.observeEventType(.Value, withBlock: { snapshot in

Cloud Firestore Security Rules: User private rules not working

Your rules actually don't apply at all to the query you're showing. The rules are only going to match documents immediately within the Users collection, such as "/Users/abc". Your query is accessing a subcollection organized under documents in Users.

If you want to match document with the ID "Info" in any subcollection called also "Info" nested under "Users", your rule should look like this:

    match /Users/{userId}/Info/Info {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}

Notice how the path of the document is fully matched to the document in the query.

You might also want to read about recursive wildcards if you want to protect documents in any subcollection under a main collection.

Swift and Firestore security rules, firebase security

Addressing your questions:

This is the key line and I don't know how to configure it specific to my app.

match /some_collection/{userId}/{documents=**}

I don't know if I change the "some_collection" to my collection name or if some_collection in that sense is an actual wildcard type of parameter itself.

In the line above "some_collection" is not a firestore wildcard and you need to replace some_collection with the actual value of your collection.

Also, do I need to pass in the userID somehow from my swift application to Firestore?

Yes and it is expected that before reading or writing to/from firestore:

  1. You had already created and configured the firebase object.

    firebase.initializeApp({

    apiKey: '### FIREBASE API KEY ###',

    authDomain: '### FIREBASE AUTH DOMAIN ###',

    projectId: '### CLOUD FIRESTORE PROJECT ID ###'

    });

  2. You had already authenticated your users with firebase auth.

    firebase.auth().signInWithCustomToken(token)

    .then((user) => {

    // Signed in

    // ...

    })

    .catch((error) => {

    var errorCode = error.code;

    var errorMessage = error.message;

    // ...

    });

Passing the userId is done by the firebase object when you call db. collection(“col123”).add or any other method. If you look at how firestore is initialized:

var db = firebase.firestore();

You will see its dependency with the firebase object.

where is userID coming from in this line?

The userID is coming from the firebase object.

I believe this block is to allow any authenticated user, so I'm just trying to explore each step.

Yes, the last rules allow any authenticated user to read and write from/to the subcollections/documents wildcard {userId}.

Lastly it is also expected that there is some naming consistency in the ids of your firestore documents or subcollections.

This means when you create firestore documents, use the firebase.auth.uid as the document id.

Otherwise, the rule from above will fail because the value behind {userId} is not equal to firebase.auth.uid of the logged user.

To achieve the latter, you can refer to this answer.

I highly recommend you have a look at this video(from the firebase channel) since it elaborates more on the core concepts of firestore security rules.

I hope you find this useful.

Having problems with Firebase access rules

The rule is denying your query because Firebase security rules are not filters. Please be sure to read and understand that documentation thoroughly.

The playground allows you to perform a request for a single document, but what you're showing here is a collection query, which you can't simulate in the console. When you perform a collection query, the rules will reject any query where there is any possible document that might not allow access. Rules will not scan every single document to pick out the ones that match - that does not scale at all.

Your function hasAccess depends on the value of a variable "household" containing an individual document ID being accessed. Since you are querying for many documents, you can't use that variable to check each document.

If you want to write a rule that requires that users can only query documents that have their UID in the users field, you'll have to write that condition like this instead:

request.auth.uid in resource.data.users

This will enforce the where clause in your query.

Firebase firestore security rules not working

I tried to compare my rules with your database structure.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /sessions/{sessionID=**} {
allow read, write: if request.auth.uid != null;
}
}

Now this should allow only registered users to gain access.

Firestore Security Rules get() not working?

After reading through more docs, it appears that this solution works:

match /group/{group} {
allow read: if request.auth.uid in resource.data.members;
match /child_collection/{document=**} {
allow read: if request.auth != null;
}
}

If anyone has input on a solution using get(), that would be very helpful as well!

Firebase Authentication creates user but does not add their Info to database

Change your code to the following:

// Add a new document with a generated ID
var ref: DocumentReference? = nil
ref = db.collection("users").addDocument(data: [
"firstname": firstname,
"lastname": lastname,
"uid": result!.user.uid
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}

Using this print statement print("Error adding document: \(err)") you can know exactly what the error is.

Also change your security rules to the following:

// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}


Related Topics



Leave a reply



Submit