Swift / Firebase: How do I properly store a Facebook user into Firebase database when they create an account?

浪尽此生 提交于 2019-12-23 09:52:52

问题


I'm trying to save users to my firebase database. I'm using a FBSDKLoginManager() to create an account / log in. Upon account creation, I want to store the users into my firebase database. I can currently log the user in and their email shows up in the Auth tab of firebase (see screenshot), but my updateChildValues doesn't seem to be having any affect (also see screenshot).

Am I placing the updateChildValues in the right place? It's currently place within signInWithCredential. I also have to perform an FBSDKGraphRequest to get the info I'm interested in storing in my firebase database.

The Auth tab of my firebase shows the authentication is working:

But the Database isn't being updated:

    func showLoginView() {
    let loginManager = FBSDKLoginManager()
    loginManager.logInWithReadPermissions(fbPermissions, fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in

        if ((error) != nil) {
            print("Error loggin in is \(error)")
        } else if (result.isCancelled) {
            print("The user cancelled loggin in")
        } else {
            // No error, No cancelling:
            // using the FBAccessToken, we get a Firebase token
            let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)

            // using the credentials above, sign in to firebase to create a user session
            FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
                print("User logged in the firebase")

                // adding a reference to our firebase database
                let ref = FIRDatabase.database().referenceFromURL("https://project-12345.firebaseio.com/")

                // guard for user id
                guard let uid = user?.uid else {
                    return
                }

                // create a child reference - uid will let us wrap each users data in a unique user id for later reference
                let usersReference = ref.child("users").child(uid)

                // performing the Facebook graph request to get the user data that just logged in so we can assign this stuff to our Firebase database:
                let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"])
                graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

                    if ((error) != nil) {
                        // Process error
                        print("Error: \(error)")
                    } else {
                        print("fetched user: \(result)")

                        // Facebook users name:
                        let userName:NSString = result.valueForKey("name") as! NSString
                        self.usersName = userName
                        print("User Name is: \(userName)")
                        print("self.usersName is \(self.usersName)")

                        // Facebook users email:
                        let userEmail:NSString = result.valueForKey("email") as! NSString
                        self.usersEmail = userEmail
                        print("User Email is: \(userEmail)")
                        print("self.usersEmail is \(self.usersEmail)")

                        // Facebook users ID:
                        let userID:NSString = result.valueForKey("id") as! NSString
                        self.usersFacebookID = userID
                        print("Users Facebook ID is: \(userID)")
                        print("self.usersFacebookID is \(self.usersFacebookID)")
                    }
                })

                // set values for assignment in our Firebase database
                let values = ["name": self.usersName, "email": self.usersEmail, "facebookID": self.usersFacebookID]

                // update our databse by using the child database reference above called usersReference
                usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
                    // if there's an error in saving to our firebase database
                    if err != nil {
                        print(err)
                        return
                    }
                    // no error, so it means we've saved the user into our firebase database successfully
                    print("Save the user successfully into Firebase database")
                })
            }
        }
    })
}

Update:

Apparently after 10 minutes or so, the database was updated with empty Facebook data... Not sure why it's taking so long. Here's a screenshot:


回答1:


You should only update the values when the completion block graphRequest.startWithCompletionHandler is executed because that's when you will get your data from the Facebook!. usersReference.updateChildValues needs to be inside graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in the completion block. I have attached it below. Try it!!

func showLoginView() {
    let loginManager = FBSDKLoginManager()
    loginManager.logInWithReadPermissions(fbPermissions, fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in

        if ((error) != nil) {
            print("Error loggin in is \(error)")
        } else if (result.isCancelled) {
            print("The user cancelled loggin in")
        } else {
            // No error, No cancelling:
            // using the FBAccessToken, we get a Firebase token
            let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)

            // using the credentials above, sign in to firebase to create a user session
            FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
                print("User logged in the firebase")

                // adding a reference to our firebase database
                let ref = FIRDatabase.database().referenceFromURL("https://project-12345.firebaseio.com/")

                // guard for user id
                guard let uid = user?.uid else {
                    return
                }

                // create a child reference - uid will let us wrap each users data in a unique user id for later reference
                let usersReference = ref.child("users").child(uid)

                // performing the Facebook graph request to get the user data that just logged in so we can assign this stuff to our Firebase database:
                let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"])
                graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

                    if ((error) != nil) {
                        // Process error
                        print("Error: \(error)")
                    } else {
                        print("fetched user: \(result)")

                        // Facebook users name:
                        let userName:NSString = result.valueForKey("name") as! NSString
                        self.usersName = userName
                        print("User Name is: \(userName)")
                        print("self.usersName is \(self.usersName)")

                        // Facebook users email:
                        let userEmail:NSString = result.valueForKey("email") as! NSString
                        self.usersEmail = userEmail
                        print("User Email is: \(userEmail)")
                        print("self.usersEmail is \(self.usersEmail)")

                        // Facebook users ID:
                        let userID:NSString = result.valueForKey("id") as! NSString
                        self.usersFacebookID = userID
                        print("Users Facebook ID is: \(userID)")
                        print("self.usersFacebookID is \(self.usersFacebookID)")

                        //graphRequest.startWithCompletionHandler may not come back during serial
                        //execution so you cannot assume that you will have date by the time it gets
                        //to the let values = ["name":
                        //By putting it inside here it makes sure to update the date once it is
                        //returned from the completionHandler
                        // set values for assignment in our Firebase database
                        let values = ["name": self.usersName, "email": self.usersEmail, "facebookID": self.usersFacebookID]

                        // update our databse by using the child database reference above called usersReference
                        usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
                            // if there's an error in saving to our firebase database
                            if err != nil {
                                print(err)
                                return
                            }
                            // no error, so it means we've saved the user into our firebase database successfully
                            print("Save the user successfully into Firebase database")
                        })
                    }
                })


            }
        }
    })
}



回答2:


Swift 3: (only changed it at the end, saves a lot of lines)

 func showLoginView() {
        let loginManager = FBSDKLoginManager()
        loginManager.logInWithReadPermissions(fbPermissions, fromViewController: self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in

            if ((error) != nil) {
                print("Error loggin in is \(error)")
            } else if (result.isCancelled) {
                print("The user cancelled loggin in")
            } else {
                // No error, No cancelling:
                // using the FBAccessToken, we get a Firebase token
                let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)

                // using the credentials above, sign in to firebase to create a user session
                FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
                    print("User logged in the firebase")

                    // adding a reference to our firebase database
                    let ref = FIRDatabase.database().referenceFromURL("https://project-12345.firebaseio.com/")

                    // guard for user id
                    guard let uid = user?.uid else {
                        return
                    }

                    // create a child reference - uid will let us wrap each users data in a unique user id for later reference
                    let usersReference = ref.child("users").child(uid)

                    // performing the Facebook graph request to get the user data that just logged in so we can assign this stuff to our Firebase database:
                    let graphRequest : FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, email, name"]).start{
                        (connection, result, err) in

                        if ((error) != nil) {
                            // Process error
                            print("Error: \(error)")
                        } else {
                            print("fetched user: \(result)")

                            let values: [String:AnyObject] = result as! [String : AnyObject]

                            // update our databse by using the child database reference above called usersReference
                            usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
                                // if there's an error in saving to our firebase database
                                if err != nil {
                                    print(err)
                                    return
                                }
                                // no error, so it means we've saved the user into our firebase database successfully
                                print("Save the user successfully into Firebase database")
                            })
                        }
                    })


                }
            }
        })
    }


来源:https://stackoverflow.com/questions/39430820/swift-firebase-how-do-i-properly-store-a-facebook-user-into-firebase-database

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