How to access user_location in Facebook Login? - ios

I'm requesting the permissions like this:
fbLoginManager.logIn(withReadPermissions: ["public_profile", "email", "user_friends", "user_location"], from: self) { (result, error) in
Upon signup I can see it is asking me for the user_location:
let request = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"first_name, last_name, user_location"], httpMethod: "GET")
request?.start(completionHandler: { (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(String(describing: error))")
}
else
{
print(result!)
}
let data:[String:AnyObject] = result as! [String : AnyObject]
})
But it seems the key is missing:
Error: Optional(Error Domain=com.facebook.sdk.core Code=8 "(null)" UserInfo={com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey=0, com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey=400, com.facebook.sdk:FBSDKErrorDeveloperMessageKey=(#100) Tried accessing nonexisting field (user_location) on node type (User), com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode=100, com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey={
body = {
error = {
code = 100;
"fbtrace_id" = Hp3weSaqfI7;
message = "(#100) Tried accessing nonexisting field (user_location) on node type (User)";
type = OAuthException;
};
};
code = 400;
}})
fatal error: unexpectedly found nil while unwrapping an Optional value
But according to the docs, it should be on the user object. Thanks

But according to the docs, it should be on the user object.
No, it should not.
You are confusing the name of the permission - user_location - with the name of the actual field of the user object - location.
https://developers.facebook.com/docs/graph-api/reference/user/:
location
Page
The person's current location as entered by them on their profile. This field is not related to check-ins

Related

How to retrieve Email from Facebook SDK

Note: please do not close as duplicate, I went through almost every existing thread here on Stackoverflow, but my problem is still not solved.
This is my Swift 3 function with the latest Facebook SDK:
let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,name"], tokenString: token?.tokenString, version: nil, httpMethod: "GET")
_ = req?.start(completionHandler: { (connection, result, error : Error?) -> Void in
if(error == nil) {
print("result \(result)")
} else {
print("error \(error!)")
}
})
Result:
result Optional({
id = 102080884567XXXXX;
name = "David Seek";
})
Email permission is approved:
Also the App is in live mode:
I have checked the reference guide, but I can't find my mistake.
My problem is, that I'm saving the facebookID as Email adress into my backend and I'm trying to figure out why... Therefore I have tried the provided code on top, but I'm not receiving the Email.
let result = FBSDKApplicationDelegate.sharedInstance().application(application,
open: url,
sourceApplication: sourceApplication,
annotation: annotation)
if result {
let token = FBSDKAccessToken.current()
let fieldsMapping = [
"id" : "facebookId",
"name" : "name",
"birthday": "birthday",
"first_name": "fb_first_name",
"last_name" : "fb_last_name",
"gender": "gender",
"email": "email"
]
backendless?.userService.login(withFacebookSDK: token, fieldsMapping: fieldsMapping, response: { (user: BackendlessUser?) in
}, error: { (fault: Fault?) -> Void in
print("Server reported an error: \(fault)")
})
}
I'm receiving every information, but the Email...
What am I missing? Help is very appreciated.
Email permission is granted:
That is not what that screenshot shows. It shows that it is approved, meaning your app can ask users for it. But it still has to ask.
Make sure that has happend successfully - either by debugging the access token, or via an API call to /me/permissions
You need to ask the user for permission during login.

Get game request ID / Access Facebook game request notification content

I am trying to send requests with data to Facebook friends in my app. The requests are successfully sent and I do get notifications. However the message on the notifications is not what I specify (the notification I get is xxxxx sent you a request. I specified Please help me with 5 lives). Also, I can't access any data of the request received.
This is how I'm sending the request:
func sendLifeRequest(index: Int) {
let content = FBSDKGameRequestContent()
content.message = "Please help me with 5 lives"
content.data = "5lives"
let id = facebookFriends[index].id as NSString
var to: [NSString] = [NSString]()
to.append(id)
content.recipients = to
FBSDKGameRequestDialog.show(with: content, delegate: self)
}
This is how I'm trying to get it in the other end:
FBSDKGraphRequest(graphPath: "https://graph.facebook.com/me/apprequests?access_token=" + FBSDKAccessToken.current().tokenString, parameters: nil).start(completionHandler: { (connection, user, requestError) -> Void in
print(requestError) // prints nil
print(user)
})
print(user) prints:
Optional({
id = "https://graph.facebook.com/me/apprequests";
"og_object" = {
id = xxxxxxxxxxxxx;
type = website;
"updated_time" = "2016-10-19T05:32:20+0000";
};
share = {
"comment_count" = 0;
"share_count" = 0;
};
Update: I found out that if I copy the request ID and copy it for graph path it works. Does anyone knows how to get this ID from receivers end
func gameRequestDialog(_ gameRequestDialog: FBSDKGameRequestDialog!, didCompleteWithResults results: [AnyHashable : Any]!) {
print("request sent")
print(results) // copied ID from here
}
and pasted...
FBSDKGraphRequest(graphPath: THE ID HERE, parameters: nil).start(completionHandler: { (connection, user, requestError) -> Void in
print(requestError) // prints nil
print(user)
})
now print user prints:
Optional({
application = {
category = Games;
id = xxxxxxxxxxxx;
link = "https://www.facebook.com/games/?app_id=1841299476156545";
name = "Crazy Traffic Saga";
};
"created_time" = "2016-10-24T21:25:34+0000";
data = 5lives;
from = {
id = xxxxxxxxxxxx;
name = "xxxxxxxxxxxxxx";
};
id = xxxxxxxxxxxx;
message = "Please help me with 5 lives";
})
The problem is I copied when I log in with the user sending and copied to the user receiving. I still can't just access it just by code from the receiver.
Facebook documentation on Game request says:
"In order to read all the requests for a recipient for you can query the graph as shown below using the recipient's USER ACCESS TOKEN. This will return a list of request ids for that user in the app.
GET https://graph.facebook.com/me/apprequests?access_token=[USER ACCESS TOKEN]"
But thats what I was doing at first...
I found it. the request should be "/me/apprequests"
so:
FBSDKGraphRequest(graphPath: "/me/apprequests", parameters: nil).start(completionHandler: { (connection, user, requestError) -> Void in
})

How do I get user record in CloudKit?

I can fetch the userRecordID, but I get an error whenever I try to fetch the record associated with that ID. Any suggestions? Code and error below:
myContainer.fetchUserRecordID { (thisID, thisError) in
if let userError = thisError {
print("DEBUG: error getting user id; \(userError)")
} else {
if let userID = thisID {
self.publicDatabase.fetch(withRecordID: userID, completionHandler: { (fetchedUser, fetchedError) in
if let thisError = fetchedError {
print("DEBUG: error getting user record; \(thisError)")
}
DEBUG: error getting user record; <CKError 0x174045010: "Internal Error" (1/5001); "Couldn't get a PCS object to unwrap encrypted data for field encryptedPublicSharingKey: (null)">
Error in the code, or my fault for trying beta software (iOS 10, Swift 3 & xCode-beta 8.0 beta 2 (8S162m)
From your example it is not clear if self.publicDatabase is equal to myContainer.publicCloudDatabase.
Make sure you fetch it from the same container's database, otherwise it will obviously not work.
myContainer.fetchUserRecordID { userID, error in
guard error == nil else {
print("DEBUG: error getting user id; \(userError)")
return
}
guard let userRecID = userID else {
print("DEBUG: Can't unwrap userID")
return
}
myContainer.publicCloudDatabase.fetch(withRecordID: userRecID, completionHandler: { (fetchedUser, fetchedError) in
//handle the error and the user
print("DEBUG: User fetch FINISHED!", fetchedUser)
})
}
I needed to change from publicDatabase to privateDatabase.
self.publicDatabase.fetch(withRecordID: userID, completionHandler: { (fetchedUser, fetchedError) in
to
self.privateDatabase.fetch(withRecordID: userID, completionHandler: { (fetchedUser, fetchedError) in

Unable to get Facebook permissions after HTTPMethod DELETE in Swift

I am working on an app that logs in to Facebook using the FBSDK in Swift. I also have been able to make requests to get my wall posts by using
var request: FBSDKGraphRequest
request = FBSDKGraphRequest(graphPath: "me/feed"), parameters: ["access_token": FBSDKAccessToken.currentAccessToken().tokenString], HTTPMethod:"GET")
request.startWithCompletionHandler({(connection, result, error) -> Void in
if error != nil
{
}
else
{
}
})
but I have been unable to get back results after I used the following to log out
var deletePermission = FBSDKGraphRequest(graphPath: "me/permissions/", parameters: nil, HTTPMethod: "DELETE")
deleterPermission.startWithCompletionHandler({(connection, result, error) -> Void in
if error != nil
{
}
else
{
}
})
When I log back in to the app, I am again asked to accept permissions, but when I check the expiration date for the current token with FBSDKAccessToken.currentAccessToken().expirationDate I get a date before I tried HTTPMethod: DELETE.
So I was wondering how it would be possible to get back permission for your app or renew my access token because I don't think it's working by logging back in and accepting permissions. I have used the following to log out of the app
// Log out of the database I'm using
try! FIRAuth.auth()!.signOut()
// Log out of Facebook, clear current token and logged user
FBSDKAccessToken.setCurrentAccessToken(nil)
FBSDKProfile.setCurrentProfile(nil)
I am also using `FBSDKLoginButton()' and setting the following permissions to log in
var loginButton = FBSDKLoginButton()
loginButton.readPermissions = ["public_profile", "user_friends", "user_about_me", "user_posts"]
loginButton.delegate = self
....
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
if error == nil
{
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)
// Firebase authentication
FIRAuth.auth()?.signInWithCredential(credential) {(user, error) in
if error == nil
{
// No error found get user credentials through Firebase
}
else
{
}
}}
But again after logging in and going to another ViewController by segue and I check the current token to get "me/feed" I am not getting a reply and the token's expiration date has expired. Would it be easier to create a new app in Facebook developer and set it up in Xcode or is there something I can do to get my user posts?

Facebook friends list api for swift ios

I have tried to get the facebook friends list for an IOS app, but receiving empty response from facebook.
How to get face book friends list in swift?
In Graph API v2.0 or above, calling /me/friends returns the person's friends who installed the same apps. Additionally, you must request the user_friends permission from each user. user_friends is no longer included by default in every login. Each user must grant the user_friends permission in order to appear in the response to /me/friends.
To get the list of friends who are using your app use following code:
let params = ["fields": "id, first_name, last_name, middle_name, name, email, picture"]
let request = FBSDKGraphRequest(graphPath: "me/friends", parameters: params)
request.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error != nil {
let errorMessage = error.localizedDescription
/* Handle error */
}
else if result.isKindOfClass(NSDictionary){
/* handle response */
}
}
If you want to access a list of non-app-using friends, then use following code:
let params = ["fields": "id, first_name, last_name, middle_name, name, email, picture"]
let request = FBSDKGraphRequest(graphPath: "me/taggable_friends", parameters: params)
request.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error != nil {
let errorMessage = error.localizedDescription
}
else if result.isKindOfClass(NSDictionary){
/* Handle response */
}
}
For fetching the friend list must allow user permission user_friends at the time of login.
For swift 3.0 add below code for fetching friend list:
let params = ["fields": "id, first_name, last_name, middle_name, name, email, picture"]
FBSDKGraphRequest(graphPath: "me/taggable_friends", parameters: params).start { (connection, result , error) -> Void in
if error != nil {
print(error!)
}
else {
print(result!)
//Do further work with response
}
}
I hope it works!
Remember only those friends are fetched who are using your app and u should have taken users read permission for user_friends while logging.
var fbRequest = FBSDKGraphRequest(graphPath:"/me/friends", parameters: nil);
fbRequest.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
println("Friends are : \(result)")
} else {
println("Error Getting Friends \(error)");
}
}
Refer to : https://developers.facebook.com/docs/graph-api/reference/v2.3/user/friends#read
Just making an union here that solved my problems:
From Dheeraj Singh, to get friends using your app:
var request = FBSDKGraphRequest(graphPath:"/me/friends", parameters: nil);
request.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
println("Friends are : \(result)")
} else {
println("Error Getting Friends \(error)");
}
}
And to get all facebook friends, from Meghs Dhameliya, ported to swift:
var request = FBSDKGraphRequest(graphPath:"/me/taggable_friends", parameters: nil);
request.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
println("Friends are : \(result)")
} else {
println("Error Getting Friends \(error)");
}
}
you can get friend list using taggable_friends
Graph API Reference for User Taggable Friend
/* make the API call */
[FBRequestConnection startWithGraphPath:#"/me/taggable_friends"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
}];
Swift - 4
This will only return your facebook friends using the same app.
// First you have to check that `user_friends` has associated with your `Access Token`, If you are getting false, please allow allow this field while you login through facebook.
if FBSDKAccessToken.current().hasGranted("user_friends") {
// Prepare your request
let request = FBSDKGraphRequest.init(graphPath: "me/friends", parameters: params, httpMethod: "GET")
// Make a call using request
let _ = request?.start(completionHandler: { (connection, result, error) in
print("Friends Result: \(String(describing: result))")
})
}
With user_friends permission you can have access to the list of your friends that also use your app, so if your app is not used by any of your friend, the list will be empty. See user_friends permission reference

Resources