User already authenticated in app and Firebase realtime database returns failed: permission_denied

陌路散爱 提交于 2019-12-10 21:39:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!