Firebase IOS - Impersonate User - ios

I am wanting to add to my iOS app the ability for sysadmin to login as another user as some bugs can only be recreated with certain users accounts and data.
I see the SDK has a custom token login (https://firebase.google.com/docs/auth/ios/custom-auth) can than be utilised.
I tried getting a token using firebase admin sdk
(https://firebase.google.com/docs/auth/admin/create-custom-tokens#python)
However that token when passed in via the SDK is rejected as being invalid.
Is this possible or do I have to implement this in a different way ? , currently my firebase rules are along these lines.
"rules": {
"users":
{
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
"races":
{
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
Do I simply need to redefine the rules to allow for a superuser access and then within the app use that users userid?

Related

Firebase Realtime Database Security Rules for prevent create/delete not working

I saw in several places that the way to prevent create and delete was with data.exists() && newData.exists(). But when I implement them in these rules, I can still create and delete to my liking when I'm logged in. What am I doing wrong? My goal is to let authenticated users update, but not create or delete.
"rules": {
"listings": {
".read": true,
".write": "data.exists() && newData.exists() && auth != null",
},
}
My guess is that you want to allow the user to update a specific listing, and not all listings at once.
In that case you should define the .write rule on each specific listing:
"rules": {
"listings": {
".read": true,
"$listingid": {
".write": "data.exists() && newData.exists() && auth != null",
}
},
}
So with this, a user can update any existing listing, but not all listings at one.

setting rules for a specific attribute in Firebase Realtime database

EDIT: this will also not work if I will set ".read": "true"
in any child or any sub-tree including the rules root (this is not showing here in the examples).
In my app, which manage user's wedding details such as guests, I want to let the guests write to the "arrive" field only if the "invited" field is exists (actually if it will be true , but I checked if it exists just for testing). However, I didn't manage to do this since in the Firebase console it's says that the simulated set is denied :
The rules in the Firebase console:
{
"rules": {
"Users": {
"$uid":{
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
},
".indexOn": "email"
},
"Guests":{
"$uid":{
"$guest_id":{
"arrive":{
".read": "$uid === auth.uid",
".write": "root.child('Guests/'+ $uid + '/' + $guest_id +'/invited').exists()"
}
}
}
}
}
}
The JSON example I wrote in the Rules Playground in the console:
{
"Guests": {
"user_1": {
"guest_1": {
"arrive": false,
"invited": true
}
}
}
}
The location path in the Rules Playground:
/Guests/user_1/guest_1/arrive
I tried several approaches and they didn't work. For example:
".write": "data.parent().child('invited').exists()"
or
".write": "root.child('Guests').child($uid).child($guest_id).child('invited').exists()"

Allow another user to read/write data Firebase Database

I have a database tree like so
users
-UID
--items
---all the data
I would like to add something under UID like shared:another-UID and allow the other UID to read and write everything under items.
For example:
users
-UID
--shared:different_UID
--items
---all the data
My current rules are like this
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
How would I change my rules to allow this?
In that case your rules would become:
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && (auth.uid == $uid || data.child('shared').val() === auth.uid)",
".write": "auth != null && (auth.uid == $uid || data.child('shared').val() === auth.uid)"
}
}
}
}
So in words: the user can read/write this data if the key is the same as their user ID, or if their user ID is stored in the shared property under the data.

firebase realtime database rules, give access to user to access another user data

i want to give access to users profile to specific users that are set by the users themselves
in this rules i want to let $userid to be able to access $user_id data
(if $user_id exist in allow_list/$userid/), i tried root.child('allow_list/'+auth.uid+'/$user_id').exists())" but its not working
this is my rules for now, not working
"users_private": {
"$user_id": {
".write": "auth != null && $user_id === auth.uid",
".read":"(auth != null) && ($user_id === auth.uid
|| root.child('allow_list/'+auth.uid+'/$user_id').exists())"
}
},
"allow_list":{
"$userid": {
//ignore these rules they are working
".read":"auth != null && $userid === auth.uid" ,
"$user_id": {
".write": "($userid == auth.uid || $user_id == auth.uid )&&
( $userid!=$user_id)",
}
}
},
I found out how, hope this help someone.
I added .child, so the rule will be like this:
|| root.child('allow_list/'+auth.uid+'/').child($user_id).exists())

How prevent username from duplicate signUp in Firebase? [duplicate]

This question already has answers here:
Firebase android : make username unique
(4 answers)
Closed 6 years ago.
I want to prevent duplicate username while signUp form what user entered. I have created email login like below, firtly createUser and then auth it setValue with user dictionary.
But I stack with Firebase security settings and how to check handle this situation.
REF_BASE.createUser(email, password: pwd, withValueCompletionBlock: { ..
REF_BASE.authUser(email, password: pwd, withCompletionBlock: { ..
REF_USERS.childByAppendingPath(uid).setValue(user)
This handling always response error.
REF_USERS.childByAppendingPath(uid).childByAppendingPath("username").setValue(user["username"]) { (error: NSError!, result: Firebase!) in
if error != nil {
print(error.localizedDescription)
}
else {
self.REF_USERS.childByAppendingPath(uid).setValue(user)
}
}
This is my security rules, How Can I fix everything to be prevented from duplicate user?
"users": {
".read": "auth !== null",
"$user": {
"username": {
".read": "auth !== null",
".write": "newData.val() === auth.uid && !data.exists()"
}
}
},
Update:
From Frank's answer, but I don't know what I need to do while signUp new user for swift in this situation.
app : {
users: {
"some-user-uid": {
email: "test#test.com"
username: "myname"
}
},
usernames: {
"myname": "some-user-uid"
}
}
Need I add same user uid at the same time for two different nodes? If someone explain it in Swift. It would be great.
"users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.provider === 'password'",
"username": {
".validate": "
!root.child('usernames').child(newData.val()).exists() ||
root.child('usernames').child(newData.val()).val() == $uid"
}
}
}
I couldn't add new user informations to usernames parent node. It's needed another security rules?
If you are trying to prevent duplicate Firebase usernames, that can be done right at the createUser stage.
Assume a dialog is presented to new user asking to create an account: this will get their desired userName and password.
Send that to createUser and if there's an error (because it already exists) notify them and ask for a different userName:
myRootRef.createUser(email, password: pw, withValueCompletionBlock: { error, result in
if error != nil {
self.errMsgField.stringValue = "email/username in use, try again"
} else {
let uid = result["uid"] as! String //the uid of the new user
print("user created as \(uid)")
self.authUserWithAuthData( email, password: pw ) //auth the user
}
})
After the user is created you would probably add their info the /users node as well.

Resources