Get facebook user groups names - swift

I'm looking for a way to get the names (names only) for all the groups a user is a member of. I'm not looking for publishing permissions or anything tricky. All I found online is how to get the groups a user is an admin of.
Edit
After searching some more, this is what i've got:
func returnUserData() {
let userRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
userRequest.start(completionHandler: { (connection, result, error) -> Void in
if ((error) != nil) {
// Process error
print("Error: \(error.debugDescription)")
} else {
guard let data = result as? [String:Any] else {
return
}
guard let userID = data["id"] else {
return
}
let groupsRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "\(userID)/groups", parameters: ["fields":"name"])
groupsRequest.start(completionHandler: { (connection, result, error) -> Void in
if ((error) != nil) {
// Process error
print("Error: \(error.debugDescription)")
} else {
print("\(result.debugDescription)")
}
})
}
})
}
Thing is that it doesn't work. The error is not nil but the result is 0 which is not true.
Please help :)
Thanks

Related

How to set user name to UITextField from FBSDKGraphRequest result

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)
}
})

Use of Unresolved Identifier firebase function

I've defined the function sendDataToDatabase but for some reason it's not resolving photoUrl?
I've been trying to figure out what might be causing this for 6 hours now and can't seem to find a solution, if anyone could provide some help it would be appreciated.
#IBAction func shareButton_TouchUpInside(_ sender: Any) {
ProgressHUD.show("Waiting...", interaction: false)
if let profileImg = self.selectedImage, let imageData = profileImg.jpegData(compressionQuality: 0.1) {
let photoId = NSUUID().uuidString
let storageRef = Storage.storage().reference(forURL: "manifest-bit-233115.appspot.com").child("posts").child(photoId)
storageRef.putData(imageData, metadata: nil, completion: { (metadata, Error) in
if Error != nil {
return
}
storageRef.downloadURL(completion: { (URL, Error) -> Void in
if (Error != nil) {
//handle any errors
} else {
//get download url
let photoUrl = URL?.absoluteString
}
self.sendDataToDatabase(photoUrl: photoUrl!)
})
}
)}
func sendDataToDatabase(photoUrl: photoUrl!) {
let ref = Database.database().reference()
//let uid = Auth.auth().currentUser!.uid
let postsRef = ref.child("posts")
let newPostId = postsRef.childByAutoId().key
let newPostRef = postsRef.child(newPostId!)
newPostRef.setValue(["photoUrl": photoUrl])
}
There are many issues.
You have to call sendDataToDatabase only in the else branch and declare the parameters with starting lowercase letters.
The parameters are not types.
storageRef.downloadURL(completion: { (url, error) -> Void in
if let error = error {
//handle any errors
} else {
//get download url
let photoUrl = url!.absoluteString
self.sendDataToDatabase(photoUrl: photoUrl)
}
})
and you have to declare the type in the function
func sendDataToDatabase(photoUrl: String) { ...
This won't work:
storageRef.downloadURL(completion: { (URL, Error) -> Void in
if (Error != nil) {
//handle any errors
} else {
//get download url
let photoUrl = URL?.absoluteString
}
self.sendDataToDatabase(photoUrl: photoUrl!)
})
photoUrl will only be available within the else clause, since that's where it's defined, and you can not use it outside of that scope.
Also, this:
func sendDataToDatabase(photoUrl: photoUrl!)
should probably be:
func sendDataToDatabase(photoUrl: String)
It's also a good idea to not name variables URL and Error, since they are identical to the URL and Error classes. Name them url and error instead.

Swift Firebase Facebook Login - Gets Name, but email returns nil

Recently my facebook login hasn't been working. It doesn't save into my database but in Firebase authentication it shows someone signed in with facebook but the email is blank. It doesn't save any data to my database which it should. The email is returning nil. My google sign in works. I've checked all the connections and they all seem to be fine. (I could have missed something) anyone have any suggestions on what connections I should check? Not sure what to do...
More Info
I printed my graph request... not sure if this helps to debug
let loginManager: FBSDKLoginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: self.facebookPermissions, from: self, handler: { (result, error) in
if error != nil {
loginManager.logOut()
let message: String = "An error has occured. \(String(describing: error))"
let alertView = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
alertView.addAction(UIAlertAction(title: "Ok ", style: UIAlertActionStyle.default, handler: nil))
self.present(alertView, animated: true, completion: nil)
} else if (result?.isCancelled)! {
// user cancelled login
loginManager.logOut()
} else {
let accessToken = FBSDKAccessToken.current()
guard let accessTokenString = accessToken?.tokenString else { return }
let credential = FacebookAuthProvider.credential(withAccessToken: accessTokenString)
Auth.auth().signIn(with: credential) { (user, error) in
if (error != nil) {
// handle error
print(error ?? "Error")
} else {
let ref = Database.database().reference()
// guard for user id
guard let uid = user?.uid else {
return
}
let usersReference = ref.child("user_profiles").child(uid)
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"])
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
// Process error
print("Error: \(String(describing: error))")
} else {
guard let data: [String:AnyObject] = result as? [String:AnyObject] else {
print("Can't pull data from JSON")
return
}
guard let userName: String = data["name"] as? String else {
print("Can't pull username from JSON")
return
}
guard let userID: String = data["id"] as? String else {
print("Can't pull ID from JSON")
return
}
let imgURLString = "http://graph.facebook.com/\(userID)/picture?type=large" as String
guard let userEmail: String = data["email"] as? String else {
print("Can't pull email from JSON")
print("Error: \(String(describing: error))")
return
}
// initial # posts = 0
let values = ["name": userName, "email": userEmail, "facebookID": userID, "profPicString": imgURLString] as [String : Any]
// update database with new user
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
// error in database save
if err != nil {
print(err ?? "Error saving user to database")
return
}
})
}
})
self.dismiss(animated: false, completion: nil)
// Present the main view
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "Customer Profile") {
UIApplication.shared.keyWindow?.rootViewController = viewController
self.dismiss(animated: true, completion: nil)
}
}
}
}
})
Using Swift 5 I found the email inside providerData which is an array of FIRUserInfo:
if AccessToken.current != nil {
let credential = FacebookAuthProvider.credential(withAccessToken: AccessToken.current!.tokenString)
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil || res == nil {
//...
return
}
guard let providerData = res?.user.providerData else {
//...
return
}
for firUserInfo in providerData {
print(firUserInfo.providerID)
print(firUserInfo.email ?? "Email not found")
}
}
}

FBSDKGraphRequestHandler Swift 3 error

I have tried to debug my entire app, and currently I am down to 3 errors, all the same error. I have spent hours trying to debug these last 3 errors on my own, but I haven't been successful. Of course, the 3 errors are the same, and I know once I debug one, I can debug all of them
The error is related to the Facebook SDK, specifically the FB SDK Graph Request Handler.
This is the code
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error?) {
if let error = error {
print(error.localizedDescription)
return
}
else{
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
// If already anon user exists link with new user
if Auth.auth().currentUser != nil{
Auth.auth().currentUser!.link(with: credential) { (user, error) in
// ...
}
}
let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "email,first_name, last_name, birthday, gender"], tokenString: FBSDKAccessToken.current().tokenString, version: nil, httpMethod: "GET")
req ? .start(completionHandler: {
(connection, result, error: NSError!) - > Void in
if (error == nil) {
print("result \(result)")
Auth.auth() ? .signIn(with: credential) {
(user, error) in
if error != nil {
print("Login failed. \(error)")
} else {
print("Logged in! \(user)")
FirebaseUtility.sharedInstance.setUser(user!)
let name = String.init(format: "%# %#", result.value(forKey: "first_name") as!String, result.value(forKey: "last_name") as!String)
FirebaseUtility.sharedInstance.editUserValue(name, key: "name")
if (result.object(forKey: "gender") != nil) {
let gender = result.object(forKey: "gender") as!String
FirebaseUtility.sharedInstance.editUserValue(gender.capitalized, key: "gender")
}
if (result.object(forKey: "email") != nil) {
let gender = result.object(forKey: "email") as!String
FirebaseUtility.sharedInstance.editUserValue(gender.capitalized, key: "email")
}
if self.isSignupflow == true {
FirebaseUtility.sharedInstance.sendToken()
// this user hasn't completed his profile so show him profile page
let vc: SignupViewController = SignupViewController(nibName: "SignupViewController", bundle: nil)
self.present(vc, animated: true, completion: nil)
} else {
FirebaseUtility.sharedInstance.isFirstTimeUser {
(isFirstTimeUser) in
if isFirstTimeUser {
FirebaseUtility.sharedInstance.sendToken()
// this user hasn't completed his profile so show him profile page
let vc: SignupViewController = SignupViewController(nibName: "SignupViewController", bundle: nil)
self.present(vc, animated: true, completion: nil)
} else {
// take him into app
// self.loginSuccessful()
let vc: RecordViewControllerNew = RecordViewControllerNew(nibName: "RecordViewControllerNew", bundle: nil)
vc.isBackButtonHidden = true
self.present(vc, animated: true, completion: nil)
}
}
}
}
}
}
The error that occurs is:
Cannot convert value of type '(, _, NSError!) ->Void' to expected argument type 'FBSDKGraphRequestHandler!'
and it occurs on this line of the code
req ? .start(completionHandler: {
(connection, result, error: NSError!) - > Void
Any help would be appreciated, I know once this error is solved, more errors are going to be created, but that's just how coding works :)
Thank you!
FBSDKGraphRequestHandler having optional Error? as last argument not the NSError!, so change the completion block to req?.start(completionHandler: { (connection, result, error) in from req?.start(completionHandler: { (connection, result, error: NSError!) - > Void will reduce that error.
Also after changing this you get new warning like.
Expression of type 'FBSDKGraphRequestConnection?' is unused
So simply add _ = as prefix of req?.start.
_ = req?.start(completionHandler: { (connection, result, error) in
//Add your code here
})

Can not fetch email from Facebook in Swift

EDIT: The problem with this question is a bit silly. As in the answer the problem is that I have not given the parameters which I want.
I can not get through with it anymore :) What can be the problem?
func returnUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(error)")
}
else
{
print("fetched user: \(result)")
let userName : NSString = result.valueForKey("name") as! NSString
print("User Name is: \(userName)")
let userEmail : NSString = result.valueForKey("email") as! NSString
print("User Email is: \(userEmail)")
}
})
}
I call the function like that:
func loginButton(loginButton: FBSDKLoginButton!,
didCompleteWithResult result: FBSDKLoginManagerLoginResult!,
error: NSError!) {
print("User Logged In")
if ((error) != nil)
{
// Process error
} else if result.isCancelled {
// Handle cancellations
} else {
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
if result.grantedPermissions.contains("email")
{
// Do work
returnUserData()
}
}
}
I get the error:
My problem is about the fatal error. However, I am kindly waiting for the comments on 2nd and 3rd lines of the output. Because, I get this output every time but the app runs correctly.
You must specify the parameters for the request.
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "first_name, last_name, email"])