Using the replace function in firestore security rules - firebase

I'm struggling with Firestore security rules. I want to check on a value that needs the replace function, i.e. an e-mail address. I can find some documentation in the general security docs, but that does not seem to work with Firestore.
For example this works:
allow write: if resource.data.members.data[(request.auth.token.email)] in ["admin"];
but this doesn't (and I changed the key in the members object accordingly):
allow write: if resource.data.members.data[(request.auth.token.email.replace('.' , ',')] in ["admin"];
Another option would be to have a way to use dots in the address of a query, so they don't have to be replaced like this:
var emailSanitized = email.replace('.' , '.');
db.collection('someCollection').where('members.' + emailSanitized, '==', 'admin')
Any ideas here?

A little late, but you can simulate the replace function on a string with this one :
function replace(string, replace, by) {
return string.split(replace).join(by);
}
So you need to define this function in your firestore.rules file and then you can call replace(request.auth.token.email, '.' , ',') to get the same result as request.auth.token.email.replace('.' , ',') in javascript.

There are two reasons why you might have been having issues.
The replace function was added to Security Rules after you asked your question.
The replace function uses regular expressions for the first argument and so matching on '.' will match literally everything.
Consider instead using: request.auth.token.email.replace('\\.' , ',')

var emailSanitized = email.replace('.' , '.');
db.collection('someCollection').where('members.' + emailSanitized, '==', 'admin')

Related

DynamoDB Java SDK query to match items in a list

I'm trying to use SQL IN clause kind of feature in dynamoDB. I tried using withFilterExpression but I'm not sure how to do it. I looked at similar questions as they were too old. Is there a better method to do this? This is the segment of code I have got. I have used a static List as example but it is actually dynamic.
def getQuestionItems(conceptCode : String) = {
val qIds = List("1","2","3")
val querySpec = new QuerySpec()
.withKeyConditionExpression("concept_id = :c_id")
.withFilterExpression("question_id in :qIds") // obviously wrong
.withValueMap(new ValueMap()
.withString(":c_id", conceptCode));
questionsTable.query(querySpec);
}
I need to pass qID list to fetch results similar to IN clause in SQL Query.
Please refer to this answer. Basically you need to form key list/value list dynamically
.withFilterExpression("question_id in (:qId1, :qId2, ... , :qIdN)")
.withValueMap(new ValueMap()
.withString(":qId1", ..) // just do this for each element in the list in a loop programmatically
....
.withString(":qIdN", ..)
);
Mind there is a restriction on maxItems in 'IN'

How to write and in one Compare in GOSU

I have a query below and need to combine the 2nd and 3rd .compare condition with 'AND' operator
var query = ii.join(InvoiceItem#PolicyPeriod)
.compare(PolicyPeriod#Plan, Relop.NotEquals, xyzPlan)
.compareIn(PolicyPeriod#ProdType, {Prod.TC_FREE, Prod.TC_UNIQ})
.compareIn(PolicyPeriod#Elig,{OffElig.TC_Yes})
Second compareIn statement should be like below in SQL but do not know how to combine two variables in one compare with AND operator.
if ( prodtype in ('FREE','UNIQ') and Elig = 'YES')
Any Advice!!
You can use .and() method from the QueryAPI:
var query = ii.join(InvoiceItem#PolicyPeriod)
.compare(PolicyPeriod#Plan, Relop.NotEquals, xyzPlan)
.and(\and1 -> {
and1.compareIn(PolicyPeriod#ProdType, {Prod.TC_FREE, Prod.TC_UNIQ})
and1.compareIn(PolicyPeriod#Elig, {OffElig.TC_Yes})
})
In the same manner, you can use .or() method or even combine and() and or() in one statement.

How to match space in MarkLogic using CTS functions?

I need to search those elements who have space " " in their attributes.
For example:
<unit href="http:xxxx/unit/2 ">
Suppose above code have space in the last for href attribute.
I have done this using FLOWER query. But I need this to be done using CTS functions. Please suggest.
For FLOWER query I have tried this:
let $x := (
for $d in doc()
order by $d//id
return
for $attribute in data($d//#href)
return
if (fn:contains($attribute," ")) then
<td>{(concat( "id = " , $d//id) ,", data =", $attribute)}</td>
else ()
)
return <tr>{$x}</tr>
This is working fine.
For CTS I have tried
let $query :=
cts:element-attribute-value-query(xs:QName("methodology"),
xs:QName("href"),
xs:string(" "),
"wildcarded")
let $search := cts:search(doc(), $query)
return fn:count($search)
Your query is looking for " " to be the entirety of the value of the attribute. If you want to look for attributes that contain a space, then you need to use wildcards. However, since there is no indexing of whitespace except for exact value queries (which are by definition not wildcarded), you are not going to get a lot of index support for that query, so you'll need to run this as a filtered search (which you have in your code above) with a lot of false positives.
You may be better off creating a string range index on the attribute and doing value-match on that.

SQLite: isolating the file extension from a path

I need to isolate the file extension from a path in SQLite. I've read the post here (SQLite: How to select part of string?), which gets 99% there.
However, the solution:
select distinct replace(column_name, rtrim(column_name, replace(column_name, '.', '' ) ), '') from table_name;
fails if a file has no extension (i.e. no '.' in the filename), for which it should return an empty string. Is there any way to trap this please?
Note the filename in this context is the bit after the final '\'- it shouldn't be searching for'.'s in the full path, as it does at moment too.
I think it should be possible to do it using further nested rtrims and replaces.
Thanks. Yes, you can do it like this:
1) create a scalar function called "extension" in QtScript in SQLiteStudio
2) The code is as follows:
if ( arguments[0].substring(arguments[0].lastIndexOf('\u005C')).lastIndexOf('.') == -1 )
{
return ("");
}
else
{
return arguments[0].substring(arguments[0].lastIndexOf('.'));
}
3) Then, in the SQL query editor you can use
select distinct extension(PATH) from DATA
... to itemise the distinct file extensions from the column called PATH in the table called DATA.
Note that the PATH field must contain a backslash ('\') in this implementation - i.e. it must be a full path.

How do I use regex to find FS.File on FS.Collection in meteor

How do I use regex to find FS.File on FS.Collection in meteor. My code is as follows and it is not working
partOfFileName = "*User_" + clickedResellerId + "_*";
var imgs = Images.find({fileName:{$regex:partOfFileName}});
//var imgs = Images.find();
return imgs // Where Images is an FS.Collection instance
In place of fileName I've also tried name and it is not working either. Please help
I don't think your regex is valid. Did you perhaps mean the following?
partOfFileName = ".*User_" + clickedResellerId + "_.*";
Please note that POSIX wildcard notation is different from regular expressions. in Regular expressions the * operators indicates repetition of the preceding operator (in my case a ., i.e., anything). A * by itself has no meaning, and it doesn't mean "anything" like in POSIX.

Resources