I have the following data structure:
{"applicants":[
{
"-KNbKoNzPGsz2TAQp-j9" : {
"email" : "zahavi#post.tau.ac.il",
"id" : "056042344",
"name" : "Jacob",
"prefix" : "Prof.",
"surname" : "Zahavi"
},
"-KNbWPpsrFGJBDaWK2EN" : {
"email" : "chamud#gmail.com",
"id" : "314965211",
"name" : "Ilay",
"prefix" : "Mr.",
"surname" : "Shvo"
},
"-KNd8HvkzAYi0LtG9qNj" : {
"email" : "zahavi#zpost.tau.ac.il",
"id" : "056042344",
"name" : "Jacob",
"prefix" : "Prof.",
"surname" : "Zahavi"
}]
}
}
I would like to enforce uniqueness rule on the field id, so it will not be possible to create two entries in applicants collection that has the same id value.
currently my rules are:
{
"rules": {
".read": true,
".write": true,
"Tables":{"applicants":{"id":{".indexOn":".value"}}}
}
}
I explored two possible solutions that are:
1. transaction. unfortunately i did not find a way to run transaction from a query.
2. rules. but failed to find something suitable.
Edit (from comments):
I tried the following rules:
{
"rules": {
".read": true,
".write": true,
"Tables": {
"applicants": {
"$app": {
"id": {
".indexOn": ".value",
".validate": "!root.child('Tables').child('applicants').child(newData.child('id').val()).exists()"
},
}
}
}
}
}
and I always got creation failed permission denied even for values that were not exist
Related
I'm building a private note app in Firebase realtime database, Android environment,
and now, I'd like to add authentificaion features with google sign-in in my app.
Until now, I tried several Rules in 'Rules playground', but it's not working well.
DB is like following:
{
"items" : {
"-MwtOrIBmhaoiGtSjzRl" : {
"key" : "-MwtOrIBmhaoiGtSjzRl",
"modifiedAt" : "2022-02-27 04:19:15.782677",
"string" : "test11"
},
"-MwvRBvCJ3hVJS3Qx1M3" : {
"key" : "-MwvRBvCJ3hVJS3Qx1M3",
"modifiedAt" : "2022-02-27 13:48:43.081140",
"string" : "Test2"
}
}
}
And the rules are like following:
{
"rules":{
"items": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid",
},
".indexOn": "modifiedAt"
}
}
}
In Rules playground, I tried 'get' simulation and the result is
'Simulated read denied'
{
"auth": {
"uid": "e41ac05f-6c93-40c8-add6-90bccf8ab80d",
"token": {
"sub": "e41ac05f-6c93-40c8-add6-90bccf8ab80d",
"firebase": {
"sign_in_provider": "google.com"
},
"email": "",
"email_verified": false,
"phone_number": "",
"name": ""
}
},
"resource": {
"key": "value"
},
"path": "/item",
"method": "get",
"time": "2022-02-27T14:44:13.766Z",
"isAdmin": false
}
Can I get some help?
One strange thing is that the follwing rules are not working well also.
{
"rules":{
"items": {
"$uid": {
".read": true,
".write": true,
},
".indexOn": "modifiedAt"
}
}
}
The key values you have under items are not Firebase Auth UIDs. They are push IDs randomly generated from your client app code. A push ID has nothing to do with the identity of the person who added that data.
To be clear, this value: "MwtOrIBmhaoiGtSjzRl" is not a UID. And it doesn't match the UID you're specifying here: "e41ac05f-6c93-40c8-add6-90bccf8ab80d".
If you want to use the user's UID as the key of the data to add to the database, don't use push(). You should instead build a path to the data using the user's UID in your code using setValue() as shown in the documentation.
What is the best way to match documents by tags using elasticsearch using the following setup (or modifying the setup)?
I've got my users in a firebase database, they have associated tags that define their interests:
"users" : {
"bruce" : {
"martial art" : "Jeet Kune Do",
"name" : "Bruce Lee",
"nick" : "Little Phoenix",
"tags" : {
"android" : true,
"ios" : true
}
},
"chan" : {
"account_type" : "contractor",
"martial art" : "Kung Fu",
"name" : "Jackie Chan",
"nick" : "Cannonball",
"tags" : {
"ios" : true
}
},
"chuck" : {
"martial art" : "Chun Kuk Do",
"name" : "Carlos Ray Norris",
"nick" : "Chuck"
}}
Using Flashlight + the Firebase admin SDK I'm keeping an index up to date on Bonsai/heroku, that supposedly will help me to match users with similar interests or related products.
"firebase": {
"aliases": {},
"mappings": {
"user": {
"properties": {
"name": {
"type": "string"
},
"tags": {
"properties": {
"android": {
"type": "boolean"
},
"ios": {
"type": "boolean"
}
}
}
}
}
}...
For now I can query users with certain combination of tags:
{
"query": {
"bool": {
"must" : {
"type" : {
"value" : "user"
}
},
"should": [
{
"term": {
"tags.ios": true
}
},
{
"term": {
"tags.android": true
}
}
],
"minimum_should_match" : 1
}}}
This is great but what I'm looking for is a way to:
Given a user id find other users with similar tags ordered by _score.
There will be other _type's apart from "user" using also tags, for example products so it would also be great to match products to users when they share some tags.
I get the feeling that because I'm absolutely new on elastic search I'm targeting this in the wrong way. Maybe the way the data is modeled?
Problem is that firebase kind of restricts this a lot, for instance I cannot have arrays, so that makes the tag modeling a bit weird ending in even more weird indexed data...maybe an approach could be to manipulate the data before inserting it to the index?
I need to create a validation rule in firebase to don't have repeated data like a primary key in a relational DB. Here is the code I was trying:
"roles": {
".read": "auth.uid != null",
"$rol_id": {
".write": "auth.uid != null",
".validate": "newData.hasChildren(['description', 'state'])",
"description": {
".validate": "newData.isString() &&
newData.val().matches(/[A-Za-z]$/i) &&
root.child('roles').child('$rol_id').child('description').val() !=
root.child('roles').child('$rol_id').child('description').exists()"
},
"state": {
".validate":"newData.isBoolean()"
}
}
},
The problem is that I can't enter in $rol_id unless i give it a constant value but i need it to evaluate in each object.
This is the structure from roles in firebase:
"roles" : {
"-KMohJaG6djjeBiq3oiV" : {
"creationDate" : 1468689365795,
"description" : "administrador",
"id" : "-KMohJaG6djjeBiq3oiV",
"permissions" : {
"inputs" : true,
"kardex" : true,
"outputs" : true,
"persons" : true,
"product" : false,
"rol" : true,
"sales" : true,
"supplier" : true,
"user" : true
},
"state" : true
},
}
I am wondering if it's possible to do the firebase authentication on strings? I have seen it being done on keys like -XDhabsuduydvtest <- random test key.
Now i have this structure:
{
"conversations" : {
"person1" : {
"person2" : {
"0" : 0,
"last_read" : 1460377167535
}
},
"person2" : {
"person1" : {
"0" : 0,
"last_read" : 1460377125515
}
}
},
"messages" : {
"eb-uuid-729fc0ac-49b8-48fa-a2ff-f2ada67b9e4c-person1" : {
"body" : "Dit is een test vanuit iOS",
"date" : 1460383996536,
"sender" : "eb-uuid-729fc0ac-49b8-48fa-a2ff-f2ada67b9e4c"
},
"person1-person2" : {
"-KF49xHKqnDawywJ9H0b" : {
"body" : "test message",
"date" : 1460375639190,
"sender" : "person1"
},
"-KF4Fc1KHH31O4_l0QWh" : {
"body" : "new",
"date" : 1460377125013,
"sender" : "person2"
}
}
},
"users" : {
"eb-uuid-729fc0ac-49b8-48fa-a2ff-f2ada67b9e4c" : {
"chat_enabled" : true,
"email" : "test#gmail.com",
"first_name" : "John",
"last_name" : "Smith",
"provider" : "password",
"push_muted" : false,
"push_token" : "some-push-token",
"uid" : "729fc0ac-49b8-48fa-a2ff-f2ada67b9e4c",
"username" : "johnsmith"
},
"person1" : {
"first_name" : "person",
"last_name" : "one"
},
"person2" : {
"first_name" : "person",
"last_name" : "two"
}
}
}
plus some security rule i tried, obviously i'd like to check if the uuid's are the same, and not only if one exists
{
"rules": {
"messages": {
"$conv":{
//Person can only read a conversation he/she is participating in
".write": true,
".read": true,
".indexOn": ["date"]
}
},
"users":{
"$ebuuid":{
".write": "root.child('users').child($ebuuid).hasChild('uid')",
".read": "root.child('users').child($ebuuid).hasChild('uid')"
}
},
"conversations":{
".write": "data.child('uid').val() === auth.uid",
".read": true
}
}
}
(Replaced images with text)
I'm really not sure how to go from here now .. the user has some uid but i'm not sure how to check it with whether he or she can post messages etc ..
So far not having any luck with Firebase Security rules.
I have this
{
"rules": {
"users": {
"$user_id": {
".read": true,
".write": "auth !== null && auth.uid === $user_id",
"profile": {
".validate": "newData.hasChildren(['first_name', 'last_name'])"
}
}
}
}
}
I send data and for the profile and one of them is blank... it lets it write any way. I wind up with data like so...
{
"users" : {
"simplelogin:25" : {
"profile" : {
"first_name" : "John",
"last_name" : ""
}
},
"simplelogin:26" : {
"profile" : {
"first_name" : "Bob",
"last_name" : ""
}
}
}
}
Any help on how to make the above rules work? Cant seem to get it to validate correctly.
Your validation rule is:
".validate": "newData.hasChildren(['first_name', 'last_name'])"
So the new data is valid if it has first_name and last_name properties.
You're sending this object over:
"profile" : {
"first_name" : "John",
"last_name" : ""
}
This object has a first_name and a last_name property, so it is valid according to your rule.
What you seem to want is that the properties don't only exist, but also are strings and have a minimum length. If that is indeed your requirement, you can write it into your validation rules:
"profile": {
".validate": "newData.hasChildren(['first_name', 'last_name'])",
"first_name": {
".validate": "newData.isString() && newData.val().length >= 10"
},
"last_name": {
".validate": "newData.isString() && newData.val().length >= 10"
}
}
The first .validate ensures that a profile has (at least) first_name and last_name properties. The other .validate rules ensure that they are of the correct type and minimum length.