My app allows for Facebook authentication. When the user logs in, I will like to set up a node called users that holds some of the user's information.Specifically, I will like to get the user's UID, name and profile picture from Facebook.
Here is my code so far:
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
// using the credentials above, sign in to firebase to create a user session
FIRAuth.auth()?.signIn(with: credential) { (user, error) in
print("User logged in the firebase")
// adding a reference to our firebase database
let ref = FIRDatabase.database().reference(fromURL: "https://gsignme-14416.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: nil).start{
(connection, result, err) in
if let user = FIRAuth.auth()?.currentUser{
let name = user.displayName! as String
let newImage = UIGraphicsGetImageFromCurrentImageContext()
let data: Data = UIImageJPEGRepresentation(newImage!, 0.5)!
let storage = FIRStorage.storage()
let storageRef = storage.reference(forURL: "gs://gsignme-14416.appspot.com")
let profilePicRef = storageRef.child(user.uid+"/profile_pic.jpg")
let metadata = FIRStorageMetadata()
metadata.contentType = "image/jpg"
// Upload the file
let uploadTask = profilePicRef.put(data, metadata: metadata) { metadata, error in
if (error == nil) {
self.downloadurl = metadata!.downloadURL()!.absoluteString
} else {
print("there was an error uploading the profile pic!")
}
let postObject: Dictionary<String, Any> = [
"uid": uid,
"username" : name,
"userpic" : self.downloadurl
]
if ((error) != nil) {
// Process error
print("Error: \(String(describing: error))")
} else {
print("fetched user: \(String(describing: result))")
let values: [String:AnyObject] = result as! [String : AnyObject]
// update our database by using the child database reference above called usersReference
usersReference.updateChildValues(postObject, 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")
})
}
}}}
}
Without implementing retrieving the user's photo URL from firebase storage, it works perfectly by outputting the name and UID. However, when I try to retrieve the image URL from firebase storage it crashes and nothing outputs. I am not really sure what I am doing wrong.
Below is the procedure how to upload image in storage and update link of image in DB and then how to retrieve image from link.
Update data in DB.
//// **NOTE:** store user ID globally in user auth so that you use userID here
func updateUserData(){
let dbstrPath : String! = "\(userid)"// where you wanted to store Db.
// Create dict as your DB.
let aDictUpdateValues = ["userName" : "John",
"userEmail" : "john@gmail.com",
"userPic" : "",
"uid" : userid]
// The Db is created as per your dict and file path. So create this two things specifically according to you..
dbRef!.child(dbstrPath).updateChildValues(aDictUpdateValues, withCompletionBlock: { (error, ref) in
if error == nil{
print("updated successfully")
self.uploadProfilePic()
dbRef.child(dbstrPath).setValue(aDictUpdateValues)
let aData = NSKeyedArchiver.archivedData(withRootObject: auserDetail)
print(ref)
}
else{
print("error in updation")
print(error!)
}
})
}
// Upload image in storage
func uploadProfilePic(){
var data = NSData()
data = UIImageJPEGRepresentation(ivProfile.image!, 0.8)! as NSData
// set upload path
let filePath = "\(userid)" // path where you wanted to store img in storage
let metaData = FIRStorageMetadata()
metaData.contentType = "image/jpg"
self.storageRef = FIRStorage.storage().reference()
self.storageRef.child(filePath).put(data as Data, metadata: metaData){(metaData,error) in
if let error = error {
print(error.localizedDescription)
return
}else{// store imageURL in DB.
let dbfilePath = "\(userid)/userpic" // update db userpic link.
//store downloadURL
let downloadURL = metaData!.downloadURL()!.absoluteString
//store downloadURL at database
dbRef.child(dbfilePath).updateChildValues(["userPic" : downloadURL])
}
}
}
Get image form firebase storage.
func getProfileImage(){
let dbstrPath : String! = "your_db_path" // path where link is stored in DB.
dbRef.child(dbstrPath).observeSingleEvent(of: .value, with: { (snapshot) in
// get dict of value from db.
if let aDictValue = snapshot.value! as? [String : Any] {
// call storage ref from link
self.storageRef = FIRStorage.storage().reference(forURL: aDictValue[Constant.FireBaseDBKey.kuserProfilePic]! as! String)
// Assuming your image size < 10MB.
self.storageRef.data(withMaxSize: 10*1024*1024, completion: { (data, error) in
if data != nil{ // if image found
let userPhoto = UIImage(data: data!)
self.ivProfile.image = userPhoto
}
else{ // if img not found set default image.
self.ivProfile.image = UIImage(named: "profile")
}
})
}
})
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.