问题
I am writing to the database and trying to read it, it always says: failed: permission_denied when using the user rules from Firebase. I am trying to write and read from Firebase to write the first and last name. The tree layout is below. The user logs in on the first storyboard and the read and write are on different storyboards and view controllers.
Do I need to authenticate on the same VC as where I am trying to get the information?
I am able to generate the UserID on different VC's so I don't know what could be doing it then.
WRITE
ref?.child(userID).child("FirstName").setValue(firstName.text!)
READ
if let snap = snapshot.value as? [String : AnyObject] {
if let firstNameResult = snap["FirstName"] as? String {
self.firstNameLabel.text = firstNameResult
}else{
print("Error")
}
}else{
print("User ID is not valid")
}
FIREBASE RULES
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
TREE LAYOUT
IdentificationStorage
USERID generated
FirstName
LastName
--FIX FOR READ-- Here is how the read works, the write works with just the code Ken provided below!
let ref = Database.database().reference().child("users/\(userID)")
ref.observeSingleEvent(of: .value, with: { snapshot in
guard snapshot.exists() else { return print("Invalid User ID") }
self.firstNameLabel.text = snapshot.get("FirstName") as? String
guard snapshot.exists() else { return print("Invalid User ID") }
self.lastNameLabel.text = snapshot.get("LastName") as? String
})
}
回答1:
Your rules are correct, the only issue is that when writing to your database, you need to say that the userID
is under the users
node. Remember to initialize your database like this:
let ref = Database.database().reference()
Here's your updated WRITE code:
ref.child("users/\(userID)/FirstName").setValue(firstName.text!)
Personally, I like to create an extension for DataSnapshot
to make getting fields easier:
extension DataSnapshot {
func get(_ field: String) -> Any? {
return (value as? [String : Any])?[field]
}
}
Just copy and paste that anywhere outside of a ViewController
. Using this function, you can refactor your READ code to this:
guard snapshot.exists() else { return print("Invalid User ID") }
self.firstNameLabel.text = snapshot.get("FirstName") as? String
As a sidenote, it is convention for Firebase fields to be lowerCamelCase, like variables are in Swift
.
来源:https://stackoverflow.com/questions/55929743/user-already-authenticated-in-app-and-firebase-realtime-database-returns-failed