My app is using Firebase's Facebook authentication and I have the following users collection:
{
"fsdjf34hf98wjefj" : {
"uid" : "facebook:543634634536"
},
"3298djwhy9hwd34234" : {
"uid" : "facebook:7658899965432"
}
}
I'm trying to restrict access so that a user can view only his own user:
{
"rules": {
".write": true,
"users": {
".read": "auth.uid === data.child('uid').val()",
}
}
}
I get the following error when trying to access a user from JavaScript:
Error: permission_denied: Client doesn't have permission to access the
desired data.
Does anyone know the correct syntax for the .read section? I've tried many things but I don't seem to get the hang of the logic behind it.
Assuming your collection is:
"users": {
"fsdjf34hf98wjefj" : {
"uid" : "facebook:543634634536"
},
"3298djwhy9hwd34234" : {
"uid" : "facebook:7658899965432"
}
}
Your rules will need to be something like:
{
"rules": {
"users": {
"$user": {
".read": "auth.uid === data.child('uid').val()",
}
}
}
}
The $user in there applies to every user node.
Note that the easiest way to troubleshoot such issues is by using the Simulator tab in the Firebase dashboard to simulate the operation. It will tell you exactly why the operation is allowed/rejected, while the SDK will (intentionally) only tell you that the operation was rejected.
Related
I was able to get the User document with this code
Users.findOne(userId)
also Users looks like this.
{
"_id" : "123sdasdasd",
"createdAt" : ISODate("2022-06-15T20:36:01.549+0000"),
"archived" : false,
"roles" : {
"internal" : [
"admin",
"maneger"
],
"client" : [
"admin",
"maneger",
"normal-user",
],
"other" : [
"admin",
"maneger",
"normal-user",
"manage"
],
},
"username" : "sample#gmail.com"
}
My goal here is to make sure if this user has a roles column with client.
I believe this is on the server side but part of my code looks like this.
Roles.removeUsers = (userId, groupName) => {
console.log(Users.findOne(userId)); // got document successfully
console.log(Users.findOne(userId).roles[groupName]); // got undefined
if (Users.findOne(userId).roles[groupName].length < 1) {
sampledataUpdate.$pull.userIds = userId;
}
};
The groupName could be internal, client, other or other strings.
Currently, I'm getting groupName as client.
How can I make sure if this user has client in roles column?
also another little question is if you look at the data structure above,
can I say roles as column?
_id, createdAt, archived are column?
and inside of column(roles for this case),
what is the right word to describe internal, client or other?
Would that be key?
Thank you!
I was able to do it with this way.
if (Users.find({ _id: userId, [`roles.${groupName}`]: { $exists: true }}).count()) {
// .......
}
I'm trying to restrict user access to some high-level node but want to give some users ability to read some of the subnodes.
My data structure is like that:
{
"COMPANIES" : {
"COMPANY1" : {
"id" : "COMPANY1",
"name" : "COMPANY1 COMPANY"
},
"COMPANY2" : {
"id" : "COMPANY2",
"name" : "COMPANY2 COMPANY"
}
},
"USERS" : {
"xZgFtwVyQFsPK3428YCa3NekOEF3" : {
"company" : {
"COMPANY1" : true,
"COMPANY2" : true
},
"email" : "ss#sss.com",
"uid" : "xZgFtwVyQFsPK3428YCa3NekOEF3",
"username" : ""
}
}
}
and so on.
And my rules for this:
{
"rules": {
"USERS": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
"COMPANIES": {
"COMPANY1": {
".read": "root.child('USERS').child(auth.id).child('company').child('COMPANY1').val() == true",
".write": false
}
}
}
}
The code I'm using to access this data looks like that (in Swift):
refFire.child("COMPANIES").child("COMPANY1").observe(DataEventType.value, with: { (dsnap) in
Also, I tried this one:
refFire.child("COMPANIES").queryOrdered(byChild: "COMPANY1").queryEqual(toValue: "COMPANY1").observe(DataEventType.value, with: { (dsnap) in
And this one (unfortunately, I don't really understand the idea behind queryEqual, so I've tried different approaches):
refFire.child("COMPANIES").child("COMPANY1").queryOrdered(byChild: "COMPANY1").queryEqual(toValue: "COMPANY1").observe(DataEventType.value, with: { (dsnap) in
So I want to give access to COMPANY1 to users with COMPANY1 = true in their profile (and deny everyone else). Rules seemed to be relatively straightforward but obviously I'm doing something wrong here because even users with COMPANY1 = true can't read company information, the permission is denied.
I am currently using MongoChef (4.3.0) to access an Azure Document DB (using DocumentDB protocol support for MongoDB).
The data in question is from an Application Insights continuous export has the following type of data within (there is other data there but this is the key part i am interested in...)
{
... other fields ...
"request" : [
{
"name" : "GET /images/loading_man.gif",
"count" : NumberInt(1),
"responseCode" : NumberInt(200),
"success" : NumberInt(1),
"url" : "http://<removed>.cloudapp.azure.com/<something>/images/loading_man.gif"
... other fields ...
}
]
... other fields ...
}
Using MongoChef I can perform some basic query like the following without issue;
{ "request": { $exists: true } }
but anything more complicated seems to return nothing or not run at all
{ "request.0.url": { $exists: true } }
{ "request.0.url": /.*man.*/i }
If I Export this data and Import it to my local MongoDb I am indeed able to perform such searches on the data in question without issue.
Any ideas how I could perform this type of search on the data in question without needing to export it?.
(this is a programming issue, because I want to do the above in a python program!)
Well it looks like all I needed to do was use $elemMatch!
{ "request": { $elemMatch: {url:/.*man.*/i } }}
this is as I understand the recommended way but also 'faster'?
I'm trying to make an app, where you have to choose a team name, and when the user enter his/hers team name, I want to check if the name already is in use.
teamNameTextField is a UITextField and for some reason no matter what I type in the text field, it prints "Team name is not in use". I don't know what I'm doing wrong here, can somebody help me?
My code:
rootRef.child("teams").queryOrderedByChild("teamName").queryEqualToValue(teamNameTextField.text).observeSingleEventOfType(.Value, withBlock: { (snap) in
if (snap.value is NSNull) {
print("Team name is not in use")
} else {
print("Team name is already in use")
}
})
my JSON data tree:
{
"teams" : {
"pbXvXYOKmJQqwSQZ9IlBykG7x1P2" : {
"teamName" : "Test111"
},
"owidUDkEnbCOsmNSoSFu2o2iu4y38RKJNF" : {
"teamName" : "Test222"
},
"pdnJCDmcdjsiHDFb8349HGD8372bfdhb" : {
"teamName" : "Test123"
}
}
}
My database rules:
{
"rules": {
".read": true,
".write": true
}
}
I realized the problem!
I tried to type print(teamNameTextField.text), and it printed: "Optional("Test111")"
So you have to put a ! after teamNameTextField.text, then it will only print "Test111"
Well the answer is probably no but I am curious to ask.
I have a Document which has two level of arrays in it:
{ '_id : '...' , events : [ urls : [], social_id : [] ], 'other_data' : '...' }
The code below works. What is does is update on a specific event the url array and adds to that set the event['event_url'] value (python).
db.col.update(
{ 'f_id' : venue['id'],
"events.title" : find_dict["events.title"] },
{ '$addToSet': { 'events.$.urls': event['event_url']} }
)
However in the same event I want to add a social id if not exists.
db.col.update(
{ 'f_id' : venue['id'],
"events.title" : find_dict["events.title"] },
{ '$addToSet': { 'events.$.social_id': event['social_id']} }
)
I was wandering if it's possible to merge the above commands into one and not run the update twice. I have not found anything in the documentation but I guess it's worth asking.
You can combine the two updates into a single operation by including both fields in the $addToSet object:
db.col.update(
{ 'f_id': venue['id'], "events.title": find_dict["events.title"] },
{ '$addToSet': {
'events.$.urls.': event['event_url'],
'events.$.social_id.': event['social_id']
}}
)