Firebase database Permission denied error facing using swift 4.2 - ios

guard let uid = user?.uid else {return}
let usernameValue = ["username":username]
let value = [uid: usernameValue]
Database.database().reference().child("user").updateChildValues(value, withCompletionBlock: { (err, ref) in
if let err = err{
print("failed to save user in db:", err)
}else{
print("successfully Work")
}
})
This is the error I am facing:
failed to save user in db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied}

You do not have the permission to manage the /user path in the database.
Check your Firebase security rules.

Allow unauthenticated access to your database.
Go into the Database panel in the console for you project, select the Rules tab and replace the contents with these rules:
{
"rules": {
".read": true,
".write": true
}
}
This makes your new database readable and writeable by everyone.
One more trick to avoid this problem call one of the signIn...methods of Firebase Authentication to ensure the user is signed in before accessing the database. 

Related

How To Add User To Firebase Database [duplicate]

This question already has answers here:
Firebase Permission Denied
(10 answers)
Closed 3 years ago.
This Is The Code I Plugged In To Add My User To Firebase Database With But I Have Received An Error IN My setvalue Linking To Firebase Database How Do I Fix This
[Firebase/Database][I-RDB038012] setValue: or removeValue: at
/users/HqQpSf9FjUgKWrG1bb3UTdedwNP2/HqQpSf9FjUgKWrG1bb3UTdedwNP2
failed: permission_denied
Auth.auth().createUser(withEmail: EmailTextField.text!, password: PasswrdTextField.text!) { authResult, error in
// [START_EXCLUDE]
guard let user = authResult?.user, error == nil else {
return
}
let ref = Database.database().reference()
let UsersReference = ref.child("users").child(user.uid)
// print(UsersReference.description()) : https://tvmassmedianetwork.firebaseio.com/
let uid = user.uid
let newUsersReference = UsersReference.child(uid)
newUsersReference.setValue(["username": self.UsernameTextField.text!, "email": self.EmailTextField.text!])
Change the permission rules in the firebase database console to the following:
// These rules give anyone, even people who are not users of your app,
// read and write access to your database
{
"rules": {
".read": true,
".write": true
}
}
During development, you can use the public rules in place of the default rules to set your files publicly readable and writable. This can be useful for prototyping, as you can get started without setting up Authentication. This level of access means anyone can read or write to your database. You should configure more secure rules before launching your app.
More info here:
https://firebase.google.com/docs/database/security

Firebase Realtime Database doesn't save data from sign up page

I am working on sign up page of application in Swift. The part of authentication in Firebase works well, but the database doesn't save any information I request. Can anyone help?
My code:
Auth.auth().createUser(withEmail: userEmail,password: userPassword, completion: {(User, error) in
if error != nil {
print(error as Any)
return
}
guard let uid = User?.user.uid else {return}
let ref = Database.database().reference(fromURL:"Database-URL")
let userReference = ref.child("users").child(uid)
let values = ["Firstname": userFirstName,"email": userEmail]
userReference.updateChildValues(values, withCompletionBlock: { (error, reference) in
if error != nil {
print(error as Any)
return
}
})
})
The console prints an error
Optional(Error Domain=com.firebase Code=1 "Permission denied"
UserInfo={NSLocalizedDescription=Permission denied})
By default the database in a project in the new Firebase Console is only readable/writeable by authenticated users:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
See the quickstart for the Firebase Database security rules.
Since you're not signing the user in from your code, the database denies you access to the data. To solve that you will either need to allow unauthenticated access to your database, or sign in the user before accessing the database.
Allow unauthenticated access to your database
The simplest workaround for the moment (until the tutorial gets updated) is to go into the Database panel in the console for you project, select the Rules tab and replace the contents with these rules:
{
"rules": {
".read": true,
".write": true
}
}
This makes your new database readable and writeable by everyone. Be certain to secure your database again before you go into production, otherwise somebody is likely to start abusing it.
I may not be sure but the completion for createUser doesnot give you User and error rather AuthResult and Error. So you have to get the user from result as below
Auth.auth().createUser(withEmail: email, password: password) { (authData, error) in
if let error = error {
debugPrint("FIREBASE ERROR : \(error.localizedDescription)")
} else {
if let authData = authData {
let user = authData.user //here get the user from result
self.saveToDB(user: user) . //save the user to database
}
}
}
This is the new code for firebase from may 2019. just change false to true like this:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}

How to check for Firebase permission denied?

How do I check for "permission_denied" in my swift code?! so that I can display a proper alert to user?
self.ref = Database.database().reference(withPath: "PlayerBoxes")
//
handle = ref.child(pID).observe(.value, with: { snapshot in
// Do Something
}) { (error) in
print(error.localizedDescription)
}
// Update info into Firebase, do not overwrite entire node
ref.child(self.pID).updateChildValues(sqr.toDictionary()) <-- Permission Denied
You need to use updateChildValues(withCompletionBlock:) instead.
This returns a database reference along with any raised error.
ref.child(self.pID).updateChildValues(sqr.toDictionary()) { (error, reference) in
if error != nil
{
// handle the error
print(error!.localizedDescription)
}
// you're fine, no error raised
}

firebase uid always return nil

Her is my database/rules:
{
"rules": {
".read": true,
".write": true
}
}
i am trying both way it is give me nil
FIRAuth.auth()?.createUser(withEmail: email, password: pass, completion: { (firuser, error) in
if error != nil {
print("error goes when try to user authenticated :) \(error)")
}
print("firuser : \(firuser)")
print("FIRAuth.auth()?.currentUser?.uid : \(FIRAuth.auth()?.currentUser?.uid)")
print("firuser?.uid : \(firuser?.uid)")
guard let userUID = firuser?.uid else{
print("user UID not found. should go stackoverflow ")
return
}
guard let userUID = firuser?.uid else{
print("user UID not found. should go stackoverflow ")
return
}
})
console log :
error :
Optional(Error Domain=FIRAuthErrorDomain Code=17995 "An error occurred when accessing the keychain. The #c NSLocalizedFailureReasonErrorKey field in the #c NSError.userInfo dictionary will contain more information about the error encountered" UserInfo={NSLocalizedDescription=An error occurred when accessing the keychain. The #c NSLocalizedFailureReasonErrorKey field in the #c NSError.userInfo dictionary will contain more information about the error encountered, error_name=ERROR_KEYCHAIN_ERROR, NSLocalizedFailureReason=SecItemAdd (-34018)})
firuser : nil
FIRAuth.auth()?.currentUser?.uid : nil
firuser?.uid : nil
server user added :
i was faced same problem ..but solve this way
Go to your *.xcodeproj
Go to the tab "Capabilities"
Activate "Keychain Sharing"

How do I validate if a username exists before sign up in Firebase and Swift 3?

I've incorporated a sign-up flow of five view controllers as opposed to one central VC for Firebase sign up.
Normally there would be the problem of data being lost before sign up, but I'm pushing all the entered values via segue programmatically to the final confirmation page and sending the data to Firebase for auth eventually.
My problem lies therein - I want to check if the username exists before signing up. This is imperative for the UX of my app and I can't just do this all one VC.
Here's the code I have for the UsernameViewController:
let rootRef = FIRDatabase.database().reference()
rootRef.queryOrdered(byChild: "users").queryEqual(toValue: self.chooseUsernameTextField.text!)
.observe(FIRDataEventType.value, with: { (snapshot: FIRDataSnapshot!) in
if snapshot.hasChildren() == false {
print("not found")
} else {
print("usr found")
}
});
Here's the code I have for the Firebase Database Security Rules
{
"rules": {
".read": false,
".write": false,
"users": {
".validate": "data.child('username').val() === true",
".read": true
}
}
}
and finally, a screenshot of my Data tree (My Data tree won't let me nest any new users or create a user node without a value for some reason):
Picture of Firebase Data Tree: App Name/Users
I have a nagging suspicion that my data rules and tree are configured properly to match the code, but I'm stuck in a XY problem of not knowing what to do for Firebase security to get my code of username checking complete.
Please help me! :(
If there's a user created within the Auth section of Firebase as well, then you can actually use the fetchProviders method, and if no providers are returned, you have no user in you Auth section.
FIRAuth.auth()?.fetchProviders(forEmail: email, completion: { (providers, error) in
if providers == nil {
// user doesn't exist
} else {
// user does exist
}
})
I have not tested the code but the theory would be to order by username that equals to the username you are looking for. If this snapshot exists you already have a user in the database with that name if it doesn't you do not.
Will run and test code when i have a chance to and update my post.
let rootRef = FIRDatabase.database().reference()
rootRef.child("users").queryOrdered(byChild:"username").queryEqual(toValue: self.chooseUsernameTextField.text!)
.observe(.value, with: { (snapshot) in
if snapshot.exists() == false {
print("not found")
} else {
print("usr found")
}
});
When using Firestore to save users, I did this
Auth.auth().addStateDidChangeListener({ (auth, user) in
if let id = user?.uid{
let userDoc = db.collection("users").document(id)
userDoc.getDocument { (document, error) in
if document == nil{// if user doesn't exist, create one
self.db.collection("users").document(id).setData(userProfile.toDictionary()){ error in
}
}
}
}
})

Resources