How to get the user details using mobile hub User-sign feature? - facebook

I'm using AWS Mobile Hub service for user sign-in. I follow mobile hub developer guide and i was successfully able to login using Facebook. After logging -in how to get the user details like profile picture or name or DOB etc. The developers guide of the mobile hub doesn;t explain this. Is it possible to get the details or is it only to authenticate users?

Currently the AWS Auth SDK which helps you perform Facebook SignIn doesn't support retrieving the user profile information can directly use the Facebook iOS SDK to fetch information including username, imageURL, etc.
let imageGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "picture.type(large)"])
let imageConnection = FBSDKGraphRequestConnection()
imageConnection.add(imageGraphRequest, completionHandler: { (connection, result, error) in
guard let imageResult = result as? NSDictionary else { return}
if let imageURL = URL(string:(((imageResult.value(forKey: "picture") as AnyObject).value(forKey: "data") as AnyObject).value(forKey: "url") as? String)!) {
self.imageURL = imageURL
}
})
imageConnection.start()
let userGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"])
let userConnection = FBSDKGraphRequestConnection()
userConnection.add(userGraphRequest, completionHandler: { (connection, result, error) in
guard let userResult = result as? NSDictionary else { return }
if let userName = userResult.value(forKey: "name") as? String {
self.userName = userName
}
})
userConnection.start()

Related

Retrieving user email, using FBSDKLoginKit, from an account registered with phone number only: what does "email" result returns?

I'm following iOS Academy tutorial on a Chat App. In said app, when a user logs in for the first time using Facebook, i need to retrieve the associated email and store it in my database. Lurking at YT comments ( here ) i've found out that a FB account can have no associated email if it was registered with the phone number. Quoting the literal comment:
I created my facebook account without an email (only through a phone number) it still registers the authentication however the identifier is missing. It also does not send out information to the database. Incase anyone who has only a phone has tried.
Since i need to pass the retrieved email to my Firebase Realtime database, i want to handle this issue, but i would need to know what happens when i try to retrieve an email using FBSKDLoginKit API if there is no associated email.
Since my FB has an associated email, and apparently there's no way to remove it and leave the field blank, i tried to register a new FB account with my phone number. The problem is that in order to be able to run the app on test mode and log into FB, i would need to validate it on Facebook For Developers, but to log into Developers i need an associated email. So i'm at a dead end and can't test myself.
My question is: does anyone knows what the email result returns in a FB request if there is no associated email?
Here's my code, my guess is that the function hits the return in the guard block at the commented line down below, because the email is equal to nil, but from what i've read on Youtube it seems that only the Database block is skipped while the Firebase authentication succeeds. So maybe it returns an empty string, or something else.
func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {
guard let token = result?.token?.tokenString else {
return
}
let facebookRequest = FBSDKLoginKit.GraphRequest(graphPath: "me",
parameters: ["fields" : "email, first_name"], tokenString: token,
version: nil,
httpMethod: .get)
facebookRequest.start { [weak self] _, result, error in
guard let result = (result as? [String: Any]), error == nil else {
self?.alertUserLoginError(message: "An error occurred while processing your request. Please try to sign in using Google.")
return
}
guard let firstName = (result["first_name"] as? String),
let email = (result["email"] as? String) else {
return
}
// Imo here the func returns cause email is equal to nil, but apparently that's not true.
// The database block is skipped, but the auth block down below is not.
DatabaseManager.shared.insertUser(with: chatUser, completion: { success in
// Doing other unrelated stuff
}
// The following block is run apparently, not sure why
let credential = FacebookAuthProvider.credential(withAccessToken: token)
FirebaseAuth.Auth.auth().signIn(with: credential) { authResult, error in
guard authResult != nil, error == nil else {
FBSDKLoginKit.LoginManager().logOut()
return
}
}
}
}
This is the database function in DatabaseManager class, called up above:
public func insertUser(with user: ChatAppUser, completion: #escaping (Bool) -> Void) {
database.child(user.safeEmail).setValue([
"first_name" : user.firstName
],
withCompletionBlock: { error, _ in
guard error == nil else {
completion(false)
return
}
completion(true)
})
}
func FacebookGETDataClicked(_ sender: Any)
{
let fbLoginManager : LoginManager = LoginManager()
fbLoginManager.logIn(permissions: ["email"], from: self) { (result, error) in
if (error == nil){
let fbloginresult : LoginManagerLoginResult = result!
let fbloginresultsss: Set<String> = fbloginresult.grantedPermissions
let arr = [String](fbloginresultsss)
if arr.count > 0 {
if(arr.contains("email"))
{
self.getFBUserData()
fbLoginManager.logOut()
}
}
}
}
}
func getFBUserData(){
var userProfileImage = String()
var useremail = String()
var userFullName = String()
var userID = String()
if((AccessToken.current) != nil){
GraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name,last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
let dict = result as! [String : AnyObject]
print(dict)
if let mail = (dict["email"] as? String)
{
useremail = mail
}
if let name = (dict["name"] as? String)
{
userFullName = name
}
if let id = (dict["id"] as? String)
{
userID = id
}
if let pic = dict["picture"] as? NSDictionary
{
let profilePictureObj = pic
let datas = profilePictureObj["data"] as! NSDictionary
userProfileImage = datas["url"] as! String
}
print(userID,useremail,userFullName,userProfileImage)
}
})
}
}

Get Facebook profile picture from URL

I want to upload the profile picture from Facebook to Firebase. I tried this answer: Upload Facebook image URL to Firebase Storage
However, Swift is giving me errors on the third line of code of that answer. The code is:
let dictionary = result as? NSDictionary
let data = dictionary?.object(forKey: "data")
let urlPic = (data?.objectForKey("url"))! as! String
Swift is telling me: Cannot call value of non-function type 'Any?!' after I changed the code to what Swift keeps suggesting me:
let urlPic = ((data as AnyObject).object(ForKey: "url"))! as! String
What is the code to use when I want to retrieve the profile picture from Facebook? My goal is to also store it into Firebase, but that will come after I get the profile picture first.
The answer is in Swift 1.2
I took reference here and implemented also
You can do this:
// accessToken is your Facebook id
func returnUserProfileImage(accessToken: NSString)
{
var userID = accessToken as NSString
var facebookProfileUrl = NSURL(string: "http://graph.facebook.com/\(userID)/picture?type=large")
if let data = NSData(contentsOfURL: facebookProfileUrl!) {
imageProfile.image = UIImage(data: data)
}
}
This is the way I got Facebook id:
func returnUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
println("Error: \(error)")
}
else
{
println("fetched user: \(result)")
if let id: NSString = result.valueForKey("id") as? NSString {
println("ID is: \(id)")
self.returnUserProfileImage(id)
} else {
println("ID es null")
}
}
})
}

Retrieve Facebook friends using the app - Swift 3

I am trying to retrieve a list of the user's Facebook friends that are using the app. To my knowledge, this permission is granted automatically but please do correct me if I'm wrong.
Here is the code I am using to retrieve the list. At the moment it just skips the code in the completion handler without leaving any messages in the console.
let params = ["fields": "id, first_name, last_name, name"]
FBSDKGraphRequest(graphPath: "/me/friends", parameters: params).start { (connection, result, error) in
if error != nil {
print("ERROR: \(error.debugDescription)")
}
else {
if let friendArray : NSArray = (result as! NSDictionary).value(forKey: "data") as! NSArray
{
for friend in friendArray {
print("Name \((friend as AnyObject).value(forKey: "name"))")
}
}
}
}
Unfortunately I can't seem to find any up to date documentation on this topic.

FBSDKGraphRequest to sign up Parse users is "ambiguous?"

The FBSDKGraphRequest connection handler used in the SignUpViewController of a tutorial app is now outdated. I updated it to a point where it won't error until I try to place the Parse code after the user successfully signs up. Once I put in the Parse code (to sign the user up using the FB SDK results), I get the errors "Type of expression is ambiguous without more context".
Here's what I have so far:
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, gender, email"])
graphRequest.startWithCompletionHandler ({ connection, result, error in
if error != nil {
//onError()
print(error)
return
} else {
let fbResult = result as! Dictionary<String, AnyObject>
print("FbResult \(fbResult)")
PFUser.currentUser()?["gender"] = result["gender"]
PFUser.currentUser()?["name"] = result["name"]
try PFUser.currentUser()?.save()
let userId = result["id"] as! String
let facebookProfilePictureUrl = "https://graph.facebook.com/" + userId + "/picture?type=large"
if let fbpicUrl = NSURL(string: facebookProfilePictureUrl) {
if let data = NSData(contentsOfURL: fbpicUrl) {
self.profilePic.image = UIImage(data: data)
let imageFile:PFFile = PFFile(data: data)!
PFUser.currentUser()?["image"] = imageFile
try PFUser.currentUser()?.save()
}
})
For some reason XCode hates anything after the "print fbresult" line. Here's a pastebin of the working code before the Parse code:
http://pastebin.com/dUyEvYmr
How can I update this to accept the Parse code?
Thanks!!
PS: I can confirm that I have the latest Parse and FB SDK. I'm running the latest version of XCode (7.2.1).
I came across with the same problem when going through the udemy swift class too.
My solution was:
if let fbResult = {
...
let name : NSString = (fbResult.valueForKey("name") as? NSString)!
let gender : NSString = (fbResult.valueForKey("gender") as? NSString)!
...
}
Hope it works for you!

Pulling Facebook profile pic with parse using Swift

I'm trying to pull the username and profile picture for my apps profile page. I'm using Parse and the Facebook SDK.
I have a UILabel and a UIView connected as outlets.
When I try to set the profileImageView, it gives me the error "Value of type 'UIImageView' has no member 'setImageWithURL'" Is this an upgrade with Swift?
Here is my code...
func setProfilePicture() {
FBSDKGraphRequest(graphPath: "me", parameters: nil).startWithCompletionHandler({ (connection, result, error) -> Void in
if let dict = result as? Dictionary<String, AnyObject> {
let name: String = dict["name"] as! String
let facebookID: String = dict["id"] as! String
let pictureUrl = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1"
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
self.nameLabel.text = name
PFUser.currentUser()!.setValue(name, forKey: "name")
PFUser.currentUser()!.saveInBackground()
}
})
}
if let url = NSURL(string: "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1") {
if let data = NSData(contentsOfURL: url){
self.profileImageView.contentMode = UIViewContentMode.ScaleAspectFit
self.profileImageView.image = UIImage(data: data)
}
}
Try creating a function, fbProfilePicURL, that takes a Facebook ID and returns the profile picture URL as an NSURL, then change
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
to
self.profileImageView.setImageWithURL(NSURL.fbProfilePicURL(facebookID))
Not 100% sure on this, but let me know if it works.