I'm trying to learn something about swift and facebook.
I integrated the SDK manually without using the pods and so far everything is ok!
I created a LogIn button by following some online guides and this works too!
Through this code located in the ViewController I can also print Id, First_Name, Last_Name and receive the ProfilePicture info :
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController, FBSDKLoginButtonDelegate {
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if (error == nil) {
print("Connected")
let r = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,first_name,last_name,picture.type(large)"], tokenString: FBSDKAccessToken.current()?.tokenString, version: nil, httpMethod: "GET")
r?.start(completionHandler: { (test, result, error) in
if(error == nil)
{
print(result as Any)
}
})
} else
{
print(error.localizedDescription)
}
}
func loginButtonWillLogin(_ loginButton: FBSDKLoginButton!) -> Bool {
return true
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("Disconnected")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let loginButton = FBSDKLoginButton()
loginButton.readPermissions = ["public_profile", "email"]
loginButton.center = self.view.center
loginButton.delegate = self
self.view.addSubview(loginButton)
}
}
The OutPut is this :
Optional({
email = "cxxxxxxxxx2#live.it";
"first_name" = Cxxxxxe;
id = 10xxxxxxxxxxxxx75;
"last_name" = Lxxxxxo;
picture = {
data = {
height = 200;
"is_silhouette" = 0;
url = "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=10xxxxxxxxxxxxx75&height=200&width=200&ext=1565467901&hash=AeQ-NalWNEMh91CK";
width = 200;
};
};
})
Now I don't know how to extract a single information such as the first_name in a variable to be able to print it in a label or take the url of the image to print it in the app.
if I try to change inside the login function like this :
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if (error == nil) {
print("Connected")
let r = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,first_name,last_name,picture.type(large)"], tokenString: FBSDKAccessToken.current()?.tokenString, version: nil, httpMethod: "GET")
r?.start(completionHandler: { (test, result, error) in
if(error == nil)
{
print(result!["first_name"] as Any)
}
})
} else
{
print(error.localizedDescription)
}
}
the compiler tells me : "Value of type 'Any' has no subscripts".
How can i do this?
Thanks ;)
in the result you should put
result.user
and that object is the one that contains the properties like displayName, or firstName for this matter
I created the labels and for now I solved it this way:
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if (error == nil) {
print("Connected")
let r = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,first_name,last_name,picture.type(large)"], tokenString: FBSDKAccessToken.current()?.tokenString, version: nil, httpMethod: "GET")
r?.start(completionHandler: { (test, result, error) in
if let id : NSString = (result! as AnyObject).value(forKey: "id") as? NSString {
print("id: \(id)")
self.lbl_fbid.text = "ID: \(id)"
}
if let first_name : NSString = (result! as AnyObject).value(forKey: "first_name") as? NSString {
print("first_name: \(first_name)")
self.lbl_fbdirstname.text = "First_Name: \(first_name)"
}
if let last_name : NSString = (result! as AnyObject).value(forKey: "last_name") as? NSString {
print("last_name: \(last_name)")
self.lbl_fblastname.text = "First_Name: \(last_name)"
}
if let email : NSString = (result! as AnyObject).value(forKey: "email") as? NSString {
print("email: \(email)")
self.lbl_fbemail.text = "Email: \(email)"
}
})
} else
{
print(error.localizedDescription)
}
}
Now I just have to figure out how to take the profile pic...
All done... if someone need the code i wrote this:
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if (error == nil) {
print("Connected")
let r = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,first_name,last_name,picture.type(large)"], tokenString: FBSDKAccessToken.current()?.tokenString, version: nil, httpMethod: "GET")
r?.start(completionHandler: { (test, result, error) in
if let id : NSString = (result! as AnyObject).value(forKey: "id") as? NSString {
print("id: \(id)")
self.lbl_fbid.text = "ID: \(id)"
}
if let imageURL = (((((result! as AnyObject).value(forKey: "picture")) as AnyObject).value(forKey: "data")) as AnyObject).value(forKey: "url") as? NSString{
print("img url: \(imageURL)")
let url = URL(string: imageURL as String)
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
self.img_fbprofilepic.image = UIImage(data: data!)
}
}
}
if let first_name : NSString = (result! as AnyObject).value(forKey: "first_name") as? NSString {
print("first_name: \(first_name)")
self.lbl_fbdirstname.text = "First_Name: \(first_name)"
}
if let last_name : NSString = (result! as AnyObject).value(forKey: "last_name") as? NSString {
print("last_name: \(last_name)")
self.lbl_fblastname.text = "First_Name: \(last_name)"
}
if let email : NSString = (result! as AnyObject).value(forKey: "email") as? NSString {
print("email: \(email)")
self.lbl_fbemail.text = "Email: \(email)"
}
if(error == nil)
{
print(result as Any)
}
})
} else {
print(error.localizedDescription)
}
}
Related
I am using Xcode 10, Swift 5 and I am trying to set a UITextField to just the user name I retrieved from Facebook. I have successfully retrieved the ID, Email, and Name in result but when I sent result to the text field is includes all three fields. I just want the name.
func getUserProfile() {
let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"name"], tokenString: accessToken?.tokenString, version: nil, httpMethod: "GET")
req?.start(completionHandler: { (connection, result, error : Error!) -> Void in
if(error == nil)
{
print("\(String(describing: result))")
self.FBUserName.text = "name \(String(describing: result))"
}
else
{
print("error \(String(describing: error))")
}
})
}
You can cast result to [String : Any], like so
if error != nil {
print("Error: \(error!.localizedDescription)")
} else if let result = result as? [String : Any] {
self.FBUserName.text = result["name"] as! String
}
Here is my working request
let graphRequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "email,name"])
graphRequest.start(completionHandler: { [weak self] (connection, result, error) -> Void in
if error != nil {
print("Error: \(error!.localizedDescription)")
} else if let result = result as? [String : Any], let strongSelf = self {
strongSelf.txtName.text = (result["name"] as! String)
strongSelf.txtEmail.text = (result["email"] as! String)
}
})
Hey guys actually i am trying two things here:- trying to create a new account and trying to open a screen like which appears after login but it is showing "email already exist error".
#IBAction func CreateAcccountButton(_ sender: AnyObject) {
guard let eventInterest = textBox.text,let email = EmailTestfield.text, let password = PasswordTestfield.text, let name = UsernameTestfield.text else {
print("Form is not valid")
return
}
Auth.auth().createUser(withEmail: email, password: password, completion: { (user, error) in
if let error = error {
print(error)
return
}
guard let uid = user?.uid else {
return
}
//successfully authenticated user
let imageName = UUID().uuidString
let storageRef = Storage.storage().reference().child("profile_images").child("\(imageName).png")
if let uploadData = UIImagePNGRepresentation(self.Profilepicture.image!) {
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
if let error = error {
print(error)
return
}
print (metadata)
// let downloadURL = metadata?.downloadURL()
// print("URL ", downloadURL)
if let Profilepictureurl = metadata?.downloadURL()?.absoluteString {
let values = ["name": name, "email": email,"EventInterest":eventInterest,"Password":password,"Profilepictureurl": Profilepictureurl ]
let user = User(dictionary: values as [String : AnyObject])
let customViewController = MessagesController()
customViewController.setupNavBarWithUser(user)
customViewController.fetchUserAndSetupNavBarTitle()
// customViewController.navigationItem.title = values["name"] as? String
self.dismiss(animated: true, completion: nil)
self.registeruserintoDb(uid,values: values as [String : AnyObject])
}
})
}
}
)
}
fileprivate func registeruserintoDb(_ uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference()
let usersReference = ref.child("users").child(uid)
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
if err != nil {
print(err!)
return
}
})
}
It's exactly what the error says, you already have a user with that email. Instead, use the auth.signIn method and check for currently signed in users.
I'm trying to store facebook user data into firebase database but I keep getting the error "Cannot convert Any? to expected type String"
((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil && result != nil) {
guard let fbData = result as? [String:Any] else { return }
let fbid = fbData["id"]
let name = fbData["name"]
self.ref.child("users").child(fbid).setValue([
"id": fbid,
"name": name
])
}
})
I also want to store the picture url into the database. How can I do this?
Using Facebook IOS Swift SDK and Firebase
Try my I implement this function. This is from the production app and it works well for us. I also recommend uploading profile image in Firebase storage or other storage, because after a while the profile image url is not valid.
class func getAllFacebookData(success: ((_ result: [String : Any]) -> Void)?, fail: ((_ error: Error) -> Void)?) {
guard !isGetDataFromFacebook else { return }
DispatchQueue.global(qos: .background).async {
guard let tokenString = FBSDKAccessToken.current()?.tokenString else { return }
guard let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "name,age_range,birthday,gender,email,first_name,last_name,picture.width(1000).height(1000),work,education,hometown,location, friends"], tokenString: tokenString, version: nil, httpMethod: "GET") else { return }
req.start { (connection, result, error) in
if error == nil {
guard let _result = result as? [String : Any] else { return }
let _picture = _result["picture"] as? [String : Any]
let _pictureData = _picture?["data"] as? [String : Any]
let _isSilhouette = _pictureData?["is_silhouette"] as? Bool
let userPref = UserDefaults.standard
userPref.set(_isSilhouette, forKey: "UserHasSilhouetteImage")
userPref.synchronize()
debugPrint("facebook result", _result)
isGetDataFromFacebook = true
syncUserInfoInDatabase(_result)
success?(_result)
} else {
debugPrint("request", error!)
fail?(error!)
}
}
}
}
fileprivate class func syncUserInfoInDatabase(_ userInfo: [String : Any]) {
let realmManager = RealmManager()
guard let currentUser = realmManager.getCurrentUser() else { return }
guard let userInfoModel = createUserInfoModel(userInfo) else { return }
do {
let realm = try Realm()
try realm.write {
currentUser.info = userInfoModel
}
} catch {
debugPrint("realm syncUserInfoInDatabase error", error.localizedDescription)
}
savePhoto(userInfo)
let firebaseDatabaseGeneralManager = FirebaseDatabaseGeneralManager()
firebaseDatabaseGeneralManager.updateCurrentUser(success: nil, fail: nil)
// crete a personal settings
let firUserSettingsDatabaseManager = FIRUserSettingsDatabaseManager()
firUserSettingsDatabaseManager.createStartPeopleFilterSettings(success: nil, fail: nil)
let userSearchLocationModel = UserSearchLocationModel()
userSearchLocationModel.userID = currentUser.id
userSearchLocationModel.birthdayTimeStamp = currentUser.birthdayTimeStamp
userSearchLocationModel.gender = currentUser.gender
switch currentUser.gender {
case UserPeopleFilterSettings.FilterGenderMode.female.description:
userSearchLocationModel.genderIndex = UserPeopleFilterSettings.FilterGenderMode.female.index
case UserPeopleFilterSettings.FilterGenderMode.male.description:
userSearchLocationModel.genderIndex = UserPeopleFilterSettings.FilterGenderMode.male.index
default: break
}
let firPeopleSearchDatabaseManager = FIRPeopleSearchDatabaseManager()
firPeopleSearchDatabaseManager.saveUserSearchLocationModel(userSearchLocationModel, success: nil, fail: nil)
}
private class func savePhoto(_ userInfo: [String : Any]) {
if let pictureDict = userInfo["picture"] as? [String : Any], let pictureDataDict = pictureDict["data"] as? [String : Any] {
if let urlPath = pictureDataDict["url"] as? String {
let firImageDatabaseManager = FIRImageDatabaseManager()
firImageDatabaseManager.saveProfileImage(urlPath, fileName: nil, isFacebookPhoto: true, realmSaved: nil)
}
}
}
I am new in iOS . i am trying to convert image or image url into png,or jpg format and failed .plz help me in this matter
#IBAction func FBSignInAct(sender: AnyObject) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager .logInWithReadPermissions(["email"], fromViewController: self, handler: { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result
if result.isCancelled {
return
}
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
}
}
})
}
func getFBUserData(){
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
print(result)
let url = NSURL(string: result["picture"]!!["data"]!!["url"]!! as! String)
let email:String = result["email"] as! String
let id:String = result["id"] as! String
let name:String = result["name"] as! String
self.signUpFBControl(email , fbID: id , name: name , profile_PicUrl: url!)
}
})
}
}
func signUpFBControl(email:String,fbID:String,name:String,profile_PicUrl:NSURL)
{
let data = NSData(contentsOfURL: profile_PicUrl)
let profilePic : UIImage = UIImage(data: data!)!
let image:NSData = UIImageJPEGRepresentation(profilePic,1)!
let strBase64:String = image.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
print(strBase64)
let dataDecoded:NSData = NSData(base64EncodedString: strBase64, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!
print( dataDecoded)
Alamofire.request(.POST, "\(SERVERURL)fb_login", parameters: ["email": email,"fbid": fbID,"name": name ,"profile_pic": image,"user_type":"business" ]).responseJSON { response in
let json = JSON(data: response.data!)
if json["msg"].string == "User Details" {
let data = json["user_details"][0]
print(data)
LoginValue.sharedInstance.setUserLoginInfo(data)
self.reachNextViewController()
} else {
self.alertView("Sign Up Failed", message: json["error_description"].string!, button: "Close", destructive: false,secondButton: "")
}
print(json["error_description"])
}
}
error says
The profile pic must be a file of type: jpeg, jpg, png.
Hello i am trying to retrieve my email from facebook as i am playing the facebook ios sdk using swift. IOS platform is 10, swift 3 and Xcode 8. I followed tutorials online but having trouble retrieving email.
below is my code:
if FBSDKAccessToken.current() == nil {
print("I got token")
let fbButton = FBSDKLoginButton()
fbButton.readPermissions = ["public_profile", "email", "user_friends"]
view.addSubview(fbButton)
fbButton.center = view.center
fbButton.delegate = self
self.fetchprofile()
}
else {
print("Dont have token")
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = self.view.center
loginView.readPermissions = ["public_profile", "email", "user_friends"]
loginView.delegate = self
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil {
print(error.localizedDescription)
return
}
print("I'm in")
fetchprofile()
}
func fetchprofile() {
print("Getting profile")
let parameters = ["fields": "email"]
let graphRequest:FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: parameters, httpMethod: "GET")
graphRequest.start(completionHandler: {(connection, result, error) -> Void in
if error != nil {
print("Error retrieving details: \(error?.localizedDescription)")
return
}
guard let result = result as? [String:[AnyObject]], let email = result["email"] else {
return
}
print("Email: \(email)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
self.view.backgroundColor = UIColor.red
})
}
and in my appdelegate.swift file :
//have both google and facebook signin. Google works but facebook doesn't
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation]) ||
FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
I am able to log in and log out but not able to retrieve email.
UPDATE Actually when i actually pass print(email) i can see it on the console as an optional statement. I'm having trouble displaying it without optional statment
I have solved the problem in this way:
func fetchProfile(){
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields" : "email, name, id, gender"])
.start(completionHandler: { (connection, result, error) in
guard let result = result as? NSDictionary, let email = result["email"] as? String,
let user_name = result["name"] as? String,
let user_gender = result["gender"] as? String,
let user_id_fb = result["id"] as? String else {
return
}
})
}
This solution worked well for me without the "/" in the graphPath parameter!
FBSDKGraphRequest(graphPath: "me" .....