Facebook Account Kit require an appsecret_proof argument Error - android

I'm trying to retrieve the user PhoneNumber/email using Facebook Account kit.
I'm always getting an error as response:
200: Server generated an error: 145: API calls from the server require
an appsecret_proof argument
I already Disabled the option on Facebook Developer Dash Board.
Require app secret for server API calls
Here is my code:
public void onLoginPhone(final View view) {
final Intent intent = new Intent(getActivity(), AccountKitActivity.class);
AccountKitConfiguration.AccountKitConfigurationBuilder configurationBuilder =
new AccountKitConfiguration.AccountKitConfigurationBuilder(
LoginType.PHONE,
AccountKitActivity.ResponseType.CODE); // or .ResponseType.TOKEN
// ... perform additional configuration ...
intent.putExtra(
AccountKitActivity.ACCOUNT_KIT_ACTIVITY_CONFIGURATION,
configurationBuilder.build());
startActivityForResult(intent, APP_REQUEST_CODE);
}
and this is onActivityResult:
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
#Override
public void onSuccess(final Account account) {
// Get Account Kit ID
String accountKitId = account.getId();
// Get phone number
PhoneNumber phoneNumber = account.getPhoneNumber();
String phoneNumberString = phoneNumber.toString();
// Get email
String email = account.getEmail();
}
#Override
public void onError(final AccountKitError error) {
// Handle Error
}
});

Simple solution to solve above problem, just follow following step.
Step 1 : Go to Facebook developer console
https://developers.facebook.com/
Step 2 : Select your application from the
https://developers.facebook.com/apps/
Step 3: After selecting your application Click on Account kit located at left side panel of console below the product Title.
Step 4 : After click on Account kit you see the Reuired App Secret switch button with yes/no option right side of it.
Step 5 : Turn Off (No) the Reuired App Secret from the there ( below the allow sms login )
Step 6 : Click on Save changes tab.
Step 7 : Run your application, you will got whatever you want.
If you have still any query ask me to any time. may be these help to you or other person.

I had the same problem. The three steps which solved my problem:
Turn off the option "App Require Secret"
Make sure the option "Enable Client Access Token Flow " has turned on, set
to "YES"
User this AccountKitActivity.ResponseType.TOKEN instead of AccountKitActivity.ResponseType.CODE
ResponseType.CODE will never return you the mobile number.
Hope it helps.

Related

Getting phone number from Facebook Account Kit

The Account Kit documentation states that if your began the login session with AccountKitActivity.ResponseType.TOKEN, it's possible to access the Account Kit ID, phone number and email of the current account via a call to getCurrentAccount().
Is it possible to get the user's phone number if you began with AccountKitActivity.ResponseType.CODE just like the way Saavn does it?
Yes, it's possible provided you use LoginType.PHONE in your configuration.
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
#Override
public void onSuccess(final Account account) {
String accountKitId = account.getId();
PhoneNumber phoneNumber = account.getPhoneNumber();
String phoneNumberString = phoneNumber.toString();
}
#Override
public void onError(final AccountKitError error) {
// Handle Error
}
});
This is your phone number: phoneNumberString; but, account.getEmail() will return null if LoginType.PHONE was used in your configuration.
Vice versa if you use LoginType.EMAIL in your configuration.
The purpose of using CODE instead of TOKEN is to shift the token request to your application server. The server uses the Graph api to submit the auth token and if the auth token is valid, the call returns the access token which is then used to verify the user's identity for subsequent API calls.
A graph call to validate the access token returns the account kit id plus additional metadata like the associated phone number and/or email.
{
"id":"12345",
"phone":{
"number":"+15551234567"
"country_prefix": "1",
"national_number": "5551234567"
}
}
You can fetch Account ID,Email and Phone number using below code:
let accountKit = AKFAccountKit(responseType: AKFResponseType.accessToken)
accountKit.requestAccount { (account, error) in
if(error != nil){
//error while fetching information
}else{
print("Account ID \(account?.accountID)")
if let email = account?.emailAddress,email.characters.count > 0{
print("Email\(email)")
}else if let phoneNum = account?.phoneNumber{
print("Phone Number\(phoneNum.stringRepresentation())")
}
}
}
If you have access code/token...
On server or client, you can exchange access token for mobile number and country code with this FB AccountKit API - https://graph.accountkit.com/v1.1/me/?access_token=xxxxxxxxxxxx. Here xxxxxxxxxx is your Access Token.
If you have auth code/token instead...
You can first exchange the access code for an access token on the server side (because it contains the App Secret) with this API - https://graph.accountkit.com/v1.1/access_token?grant_type=authorization_code&code=xxxxxxxxxx&access_token=AA|yyyyyyyyyy|zzzzzzzzzz. Here xxxxxxxxxx, yyyyyyyyyy and zzzzzzzzzz are the auth code, app id and app secret respectively. Once you have the access token with it, you can get the mobile number with the above mentioned API.
Good Luck.

Java based Google App Engine, Android and authentication oauth2

Authentication and app engine, there is a lot to be read about it, but a lot seems to be outdated!
Even the google pages https://developers.google.com/appengine/docs/java/endpoints/consume_android#making-authenticated-calls
Here, they talk about 'GoogleAccountCredential.usingAudience', but nowadays, you should use GoogleAuthUtil (as far as I know, please correct me if I'm wrong).
I am trying to set up an app engine as a backend to my Android app (and in future, my iOS app).
I am using Android Studio, used the 'new module' and chose app engine with cloud messaging there.
I created a simple endpoint, and have a function there, here is some code:
public class ReviewEndpoint {
// Make sure to add this endpoint to your web.xml file if this is a web application.
private static final Logger LOG = Logger.getLogger(ReviewEndpoint.class.getName());
/**
* This method gets the <code>Review</code> object associated with the specified <code>id</code>.
* #param id The id of the object to be returned.
* #return The <code>Review</code> associated with <code>id</code>.
*/
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id) {
// Implement this function
Review r = new Review();
r.setData("test!");
As you can see, this is nicely generated by Android Studio. I implemented some stuf like creating the 'review' object and return it at the end.
On the Android side, I can do this:
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null);
ReviewEndpoint ep = b.build();
Review review = ep.getReview(1L).execute();
data = review.getData();
and yes, I get 'test!' :)
Now, I want to have this authenticated. I want to know which user wrote what, so I thought I am going to use GMail account and Facebook later.
Here I'm stuck. I am able to get a token from the user on Android:
token = GoogleAuthUtil.getToken(MainScreenActivity.this, mAccount.name, "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile");
then you are able to add this token as credential to the request:
Credential cr = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token);
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), cr);
Then in the app engine I tried to get the user info, but how?
Will it be supplied as 'bearer'? How do I get this bearer token? Should I then do API request to get the data on the server?
this does not work:
OAuthService service = OAuthServiceFactory.getOAuthService();
try {
User user = service.getCurrentUser();
can anyone give me a heads up?
So finally, today, I found out how to do it! I had questions on Stackoverflow on this before and never had an answer, but these to sites gave me the answer:
https://developers.google.com/appengine/docs/java/endpoints/auth
https://developers.google.com/appengine/docs/java/endpoints/consume_android
The first shows what needs to be done on the app engine side. The second page will tell you how to get the credentials. I was quite close. I am not sure if the adjusting of the build.gradle file mentioned in the second link is necessary. What I added to the App Engine:
#Api(name = "reviewEndpoint", version = "v1", ...<<some more stuff here >>
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE})
and then get the credentials:
// Initialize the scope using the client ID you got from the Console.
final String scope = "server:client_id:" + Constants.WEB_CLIENT_ID;
credential = GoogleAccountCredential.usingAudience(activity,scope);
You have to add the e-mail address of the user:
credential.setSelectedAccountName("some-mail-address#gmail.com");
you can get the e-mail address using the account picker (also example shown when you follow the link)
and next. you do a call to the endpoint, using the credential, I think Play Services will validate the user, because if I use an e-mail that is not logged in on the device, it will not work. The following code will throw an GoogleAuthIOException :
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), id_token);
ReviewEndpoint ep = b.build();
Review review;
review = ep.getReview(1L).execute();
for testing, I've put the e-mail address I get at the server side as a string in the review object, and there it gave me the e-mail address instead of the user object being null. Ow! I forgot to tell you, you need a user argument on the app engine side. Even though you do not see the 'user' argument in the 'getReview' call above, it will be added by App Engine.
So this is how my getReview looks now:
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id, User user) {
// Implement this function
Review r = new Review();
r.setData("user == " + (user == null ? "NULL " : user.toString()));
Hope this will help someone

What is a Page ID for the place field in Post Facebook Graph API?

I am having trouble while trying to post a message on the current end-user Facebook wall with my Android Application.
So far :
The user is logged in with all the required permissions, especially
the publish_actions permission ;
I am using the last version of Facebook SDK 3.x & Graph API v2 as of May 2014
Post to wall works now as of EDIT 2, but there are issues with
privacy settings : post cannot be seen by anyone not even the
recipient who is tagged in the post ! See EDIT 2 for more details
Here is the documentation for posting a message on the user wall :
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/feed (go to Publishing)
Regarding the message that needs to be posted on the user' wall, I need to tag some friends that were previously selected by the user.
But to use the tag field I need to use the place field.
The documentation says :
Name: tags
Comma-separated list of user IDs of people tagged in this post. You cannot specify this field without also specifying a place.
Type: csv[string]
Name: place
Page ID of a location associated with this post.
Type: string
What is location page ID ? How do I get it ?
Oddly enough, in my specefic case, I am offering the possibilty to the user to share is upcoming travel on Facebook.
More oddly enough, this travel is defined by dates and a destination (name of destination + latitude & longitude). The user has the possibility to also share this travel to his friends that are located in his travel's destination hence the need to tag his friends to the wall post.
[EDIT 1]
After looking into #Tobi solutions, I managed to post a message on the end-user wall (in my case me, since I am the developper).
So far : the message is correctly displayed with a friend tagged (a dummy account I use for tests purpouses) and there is also the place : Paris, France.
Using the following search query (thanks #Tobi) search?q=Paris,France&type=place I can get the ID of Paris, France.
Since I did not code the part to retrieve the Place ID it put it manually in the code for the sake of testing the feature first.
[END OF EDIT 1]
[EDIT 2]
I noticed I forgot to add the part with the privacy values to my args Bundle. But it did not change a damn thing : my post is only visible to me alone.
Going to my Facebook wall, here is what I get :
Hovering the public parameters of the posts (a padlock icon) says "All tagged persons".
Clicking on the icon shows the list of settings with only "Only me" selected.
Why "only me" even though I specifically said me + my dummy account in the request parameters ?
Even weirder : changing the property of the publication parameters to "customized" with my dummy account does not change a damn thing as well. Just why ? Facebook is really getting on my nerve...
For the rest, the message content is correctly displayed and the related place is the good one. At least a got that correctly. But still, I just don't get the rest ...
[END OF EDIT 2]
So here is the updated code :
if (this.session != null && this.session.isOpened()) {
final Bundle args = new Bundle();
if (this.selectedContacts.isEmpty() == false) {
args.putString("message", message);
args.putString("place", "170558129707208"); //manually added Paris, France ID
String tags = "";
//here I made some modifications regarding the tags so that is built correctly
for (int it = 0; it < this.selectedContacts.size(); it++) {
final String name = this.selectedContacts.get(it).toString();
final String friendID = String.valueOf(getIdFromName(name)); // returns an int
if (it == this.selectedContacts.size())
tags += friendID;
else
tags += friendID + ",";
}
// Forgot to add privacy values to bundle !
final JSONObject privacyValues = new JSONObject(); //not android JSON, but JSON-Simple lib
privacyValues.put("value", "CUSTOM");
String allow = this.currentUser.getId() + "," + tags;
privacyValues.put("allow", allow); // to limit the visibility of this post
args.putString("privacy", privacyValues.toJSONString()); //forgot that one...
final Request shareTravelRequest = new Request(this.session, this.currentUser.getID() + "/feed",
args, HttpMethod.POST, new Request.Callback() {
public final void onCompleted(final Response response) {
//TODO
}
}
);
final Response response = shareTravelRequest.executeAndWait();
if (response.getError() == null) // in this case, no error occurred
return true;
else {
this.lastErrorMessage = response.getError().getErrorMessage();
Log.e("Something went wrong while posting Facebook message", this.lastErrorMessage);
Log.e("Error type is", response.getError().getErrorType());
Log.e("Error code is", String.valueOf(response.getError().getErrorCode()));
return false;
}
}
}
Unfortunately I must have mistaken somewhere because although the post does appear on my Facebook wall with my dummy account tagged and with the correct link to the place, my dummy account cannot see the post.
I tried creating manually the same post on my Facebook wall by using the following settings :
First I supplied a message
Second I supplied a place
Third I tagged my dummy account
Four I choose who can see this post : me and my dummy account
And finally, I post the message.
In this case, my dummy account sees the post both on its wall and on my wall.
So I would like to know what parameters I must get wrong because there is not much parameters and I just don't see why.
Thanks !
You can either use the Search and use the type place (https://developers.facebook.com/docs/graph-api/using-graph-api/v2.0#search), or, if you have positioning date, use an FQL query on the place table (https://developers.facebook.com/docs/reference/fql/place/) as described here: Facebook places: order results by distance
Use two test accounts made via Facebook Developer App settings and not a dummy account that breaks TOS. Since you request publish_actions you probably didn't submit the app for review. Unless your dummy account is a developer/tester in roles as well (which is breaking the TOS again) then your dummy account will not be able to see the post.
Only developers and testers of an unpublished application can see posts made by that application.

Using Facebook and Twitter through AndroidSocialNetworks

I am trying to integrate Facebook and Twitter in my Android app just to post some text information.
Facebook is almost working, user can log normally, but when I execute
mSocialNetworkManager.getFacebookSocialNetwork().requestPostMessage("Facebook test",
new OnPostingCompleteListener() {
#Override
public void onPostSuccessfully(int i) {
System.out.println("Facebook post success!");
}
#Override
public void onError(int i, String s, String s2, Object o) {
System.out.println("Facebook error: " + s2);
}
});
No onPostSuccessfully nor onError get called. Same thing with the demo app (it shows eternally the waiting dialog). Is it a recent change in Facebook API or something wrong with the lib?
On the other side, Twitter always returns an error when trying to SocialNetwork.REQUEST_LOGIN.
Error:
401:Authentication credentials (https://dev.twitter.com/pages/auth) were missing or incorrect. Ensure that you have set valid consumer key/secret, access token/secret, and the system clock is in sync.
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Desktop applications only support the oauth_callback value 'oob'</error>
<request>/oauth/request_token</request>
</hash>
I think consumer key and secret are correctly set.
mSocialNetworkManager = SocialNetworkManager.Builder.from(getActivity())
.twitter(SocialNetworkConstants.TWITTER_API_KEY, SocialNetworkConstants.TWITTER_API_SECRET)
.facebook().build();
Image from API keys section
Do you know why do I get that error?
Thanks in advance.
v0.3.2 includes fix for Facebook sharing.
As for Twitter,
When you created application, did you enter OAuth callback like 'oob'?
Possibly try to enter some website url as OAuth callback. Another possible issue is that you have invalid time on your phone, please check Settings -> Date & Time and insure that Automatic Date & Time checkbox is checked.

How to post a tweet from an Android app to one specific account?

I have to add an option to my game for posting highscores to twitter. The idea is that the app has it's own twitter account and the user can upload the score to this specific account with a click on a button or a menu item (haven't decided how the UI looks like yet).
I have found many tutorials like this:
http://blog.doityourselfandroid.com/2011/02/13/guide-to-integrating-twitter-android-application/
,which show how to post to twitter from apps but in all of these solutions the user needs to login with his/her own account.
Any suggestions are welcome. Thank you.
I have found a solution for this problem. Thought I share it here in case anyone has the same problem.
First you need to create the account for your app on twitter
Go to this page and log in with the created account
Move your mouse over your account name in the upper right corner and
click "My applications"
Click on "Create a new application" on the right
Fill in the form and create the application
Go to Settings and under Application type set the Access type to
"Read and Write" and save the settings
Return to the "Details" page and scroll down to the bottom and click
the "Create access token" button
Use these generated tokens and the other ones ("Consumer key" and
"Consumer secret") which are shown above these previously generated
tokens on the same page to post tweets from your app
Here's the code I used in my app:
You need to include the twitter4j-core-android-2.2.5.jar package for this. You can download it from here: http://twitter4j.org/archive/twitter4j-android-2.2.5.zip
tweet=(Button)findViewById(R.id.tweetbtn);
message=(EditText)findViewById(R.id.messagetxt);
tweet.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
String token ="<Your access token>";
String secret = "<Your access token secret>";
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer("<Your consumer key>", "<Your consumer secret>");
twitter.setOAuthAccessToken(a);
try {
twitter.updateStatus(message.getText().toString());
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
the new link for download
http://twitter4j.org/archive/twitter4j-android-2.2.5.zip
old link does not work

Categories

Resources