In my application, I'm manually setting an access token that's stored server-side. When I try and use an FB.dialog to show an invite dialog, the web view displays "An error occured with . Please try again later. API Error Code: 110 API Error Description: Invalid user id Error message: Missing user cookie (to validate session user)
I've verified that the token is valid, and I've been able to make requests requests with it.
Here's the implementation:
Facebook facebook = new Facebook("my app id");
try {
facebook.setAccessToken(authToken);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = format.parse(tokenExpiration);
facebook.setAccessExpires(date.getTime());
Bundle params = new Bundle();
params.putString("message", "Invite Friends!");
facebook.dialog(mActivity, "apprequests", params, new DialogListener() {
#Override
public void onFacebookError(FacebookError e) {
Log.e(e.getMessage(), e);
}
#Override
public void onError(DialogError e) {
Log.e(e.getMessage(), e);
}
#Override
public void onComplete(Bundle values) {
}
#Override
public void onCancel() {
}
}); .....
No callback is made for onFacebookError or onError
Figured this out, it was related to a partner's SDK messing w/ cookies.
Related
We want to integrate social login with aws. We get facebook token from facebook SDK then we pass it to AWS client. But It gives a below error.
Code:
AWSMobileClient.getInstance().initialize(SignUpActivity.this, new Callback<UserStateDetails>() {
#Override
public void onResult(UserStateDetails result) {
try {
AWSMobileClient.getInstance().federatedSignIn("graph.facebook.com", token,
new Callback<UserStateDetails>() {
#Override
public void onResult(final UserStateDetails userStateDetails) {
//Handle the result
Log.d("AA", "onResult: " + userStateDetails.getDetails());
}
#Override
public void onError(Exception e) {
Log.e("AAA", "sign-in error", e);
}
});
} catch (Exception e) {
}
}
#Override
public void onError(Exception e) {
}
});
Caused by: com.amazonaws.AmazonServiceException: 1 validation error detected: Value 'us-east-1_xxxxxxxx' at 'identityPoolId' failed to satisfy constraint: Member must satisfy regular expression pattern: [\w-]+:[0-9a-f-]+ (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: ValidationException; Request ID: fd3202ef-abxx-xxxx-xx7c-xxxxxxxxxxx)
Please provide us a solution. Thanks in advance.
You're going to need to provide more details than that. What is your request to Cognito? It looks like you may be passing in the incorrect payload for the AWS request.
Check out the AWS Cognito User Pool Auth docs: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html
I have searched on internet, but I have not found a solution for my problem.
In my app I have an option for a Facebook using the android Facebook sdk, then I get the information of user Facebook(accessToken, userId) say USER1. Is there any way to send a private message to another user say USER2 who is not a friend of USER1.
Facebook SDK doesn't contain any private message feature till date.they haven't included it due to some spam flaws.the only way you can do that use Send Dialog , though I haven't tried it.give a try.
Bundle params = new Bundle();
params.putString("to", "user_id");
params.putString("name", "tittle");
params.putString("link", "url"); // this link param is required
facebook.dialog(context, "send", params, new DialogListener() {
#Override
public void onComplete(Bundle values) {
....
}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
I've spent the better part of 2 days trying to understand and follow the "Getting Started" section in the Android SDK doc (I'm a noob, so please go slow). I've also been picking through Quickblox API documentation, Stack overflow Quickblox Q&A's, and the Quickblox sample code.
Could someone please explain how I can actually establish a very simple and basic session with the Quickblox backend?
In trying to do this myself, here's what's I've run into/discovered:
Under the section "Getting Started" (in http://quickblox.com/developers/Android) the following steps are outlined:
Initialize framework with application credentials
Create session
Login with existing user or register new one
Perform actions with QuickBlox communication services and any data entities (users, locations, files, custom objects, pushes etc.)
For #1 above, it gives the following code:
QBSettings.getInstance().fastConfigInit("961", "PBZxXW3WgGZtFZv", "vvHjRbVFF6mmeyJ");
I put the above in the OnCreate method of my activity.
Then, for #2, it says "To create an application session use this code:"
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
}
#Override
public void onError(List<String> errors) {
// errors
}
});
I also add that to my OnCreate.
For #3, I continue to use the suggested code. Is this case, I am creating a new user:
// Register new user
final QBUser user = new QBUser("userlogin", "userpassword");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
}
#Override
public void onError(List<String> errors) {
// error
}
});
Here's my full OnCreate code:
public class ChatCategoryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_category);
Toast.makeText(getApplicationContext(), "Toast Test!",
Toast.LENGTH_LONG).show();
//Initialize quickblox framework
QBSettings.getInstance().fastConfigInit("29430", "XNKu54nymZXFq3c", "3vy372mwtYwfJU7");
//create a quickblox application session
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
Toast.makeText(getApplicationContext(), "App session created!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// errors
Toast.makeText(getApplicationContext(), "Failed to create app session!",
Toast.LENGTH_LONG).show();
}
});
// Register new user
final QBUser user = new QBUser("bob1", "bobobob1");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
Toast.makeText(getApplicationContext(), "User signed up!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// error
Toast.makeText(getApplicationContext(), "User sign-up failed!",
Toast.LENGTH_LONG).show();
}
});
}
}
So, when I run it, according to the toast that fires, the app session fails to be created. Additionally, the URL that the app posts is this:
https://api.quickblox.com/session.json?application_id=29430&auth_key=XNKu54nymZXFq3c&nonce=166079749×tamp=1444750770&signature=a412ecb12db54842f6816968a734b4fc2626509d
And the response is:
{"errors":["Token is required"]}
The only place a "token" is mentioned in the Android SDK doc is here:
It's also possible to initialise the SDK with an existent QuickBlox
token. It can be interesting in cases when you build a big system and
you have the server side which generates QuickBlox tokens for
example...
The implication is that the token is not necessary. But clearly it is.
Could someone please help me with what what I am missing? I'd be very grateful for the code I need, including how to generate the token (including the SHA signature) and use it to initialise the framework, create a session, create/login a user, etc....
Many thanks!
First check: internet connection, do you have the internet permission in your manifest?
<uses-permission android:name="android.permission.INTERNET"/>
Your code to create session and user looks fine but you can only sign up once the session is created !
Using your code it would looks like that :
public class ChatCategoryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize quickblox framework
QBSettings.getInstance().fastConfigInit("29430", "XNKu54nymZXFq3c", "3vy372mwtYwfJU7");
//create a quickblox application session
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
Toast.makeText(getApplicationContext(), "App session created!",
Toast.LENGTH_LONG).show();
// Register new user
final QBUser user = new QBUser("bob1", "bobobob1");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
Toast.makeText(getApplicationContext(), "User signed up!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// error
Toast.makeText(getApplicationContext(), "User sign-up failed!",
Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onError(List<String> errors) {
// errors
Toast.makeText(getApplicationContext(), "Failed to create app session!",
Toast.LENGTH_LONG).show();
}
});
}
}
If the credentials are OK, a new user should be created. (for security reasons don't forget to reset the credentials and update your code.)
I am developing an Android app. With the impending deprecation of Facebook's offline_access permission I am trying to use the Graph API to extend the Facebook token.
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
Can anyone provide detailed code that demonstrates how to implement the code above into an android app and obtain the refreshed Facebook token?
Thank you for your time.
Update Two:
Progress (I think)!
Using the full URL with the facebook request method results in the base URL being added to the the beginning of the URL
So instead of
String refreshUrl = "https://graph.facebook.com/oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;
should use
String refreshUrl = "oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;
However I am now getting the response {"error":{"message":"Error validating application. Invalid application ID.","type":"OAuthException","code":190}}
Update One:
Here is what I have I tried. The code completes, that is OnComplete on the listerner is called, BUT the response does not contain a new access token or expiry value.
void refreshWithGraph() {
AsyncFacebookRunner extendingAsyncRunner = new AsyncFacebookRunner(facebook);
Bundle parameters = new Bundle();
//the variable currentAccessToken is obtained after authorisation is complete using currentAccessToken = facebook.getAccessToken();
String refreshUrl = "https://graph.facebook.com/oauth/access_token?client_id=12345678910&client_secret=abcdefghijklmnopqrstuvwxyz&grant_type=fb_exchange_token&fb_exchange_token="+currentAccessToken;
extendingAsyncRunner.request(refreshUrl, parameters, new RefreshListener(), null );
}
Here is my version of RefreshListener...
//REFRESH LISTENER
public class RefreshListener extends BaseRequestListener {
public void onComplete(final String response, Object state) {
try {
final JSONObject json = Util.parseJson(response);
runOnUiThread(new Runnable() {
#Override
public void run() {
tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE\nResponse is " + response);
tvRefreshToken.setText("IN REFRESH LISTENER ONCOMPLETE\nToken is " + facebook.getAccessToken());
tvRefreshExpiry.setText("IN REFRESH LISTENER ONCOMPLETE\nFacebook expiry is " + millisecToDate(facebook.getAccessExpires()));
}
}); //end runOnUiThread
} catch (JSONException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE CAUGHT JSON EXCEPTION \nResponse is " + response);
}
}); //end runOnUiThread
} catch (FacebookError fe) {
runOnUiThread(new Runnable() {
#Override
public void run() {
tvRefreshResponse.setText("IN REFRESH LISTENER ONCOMPLETE CAUGHT FACEBOOK ERROR \nResponse is " + response);
}
}); //end runOnUiThread
} //end catch Facebook error
} //end onComplete
#Override
public void onIOException(IOException e, Object state) {
tvRefreshResponse.setText("IN REFRESH LISTENER IOEXCEPTION \nException is "+ e.getLocalizedMessage());
}
#Override
public void onFileNotFoundException(FileNotFoundException e, Object state) {
tvRefreshResponse.setText("IN REFRESH LISTENER FILE NOT FOUND EXCEPTION \nException is "+ e.getLocalizedMessage());
}
#Override
public void onMalformedURLException(MalformedURLException e, Object state) {
tvRefreshResponse.setText("IN REFRESH MALFORMED URL \nException is "+ e.getLocalizedMessage());
}
#Override
public void onFacebookError(FacebookError e, Object state) {
tvRefreshResponse.setText("IN REFRESH ONFACEBOOK ERROR \nException is "+ e.getLocalizedMessage());
}
} //end RefreshListener
The code completes, that is OnComplete on the listerner is called, BUT the response does not contain a new access token or expiry value. The response is...
{"id":"https:\/\/graph.facebook.com\/oauth\/access_token","shares":78,"comments":1}
When I put the same URL (with a alphanumeric current token value) into a web browser the response DOES include an access token.
Related Info
Facebook's offline_access permission will be deprecated on 1st of May, 2012
Please don't suggest using the extendAccessTokenIfNeeded function in onResume() instead. I am also having trouble with that and it is the reason why I am looking into the Graph API token refreshing :-)
Related Stack Overflow Questions
Is it possible to extend Facebook tokens with extendAccessTokenIfNeeded in an Android app? (my question)
How would offline_access work after deprecation after May 1st?
Facebook access token can not be extended
Protecting app secret for extendAccessToken usage (Java/Android)
Relevant Facebook links
Facebook Android Tutorial
Facebook offline_access permission deprecation
To be honest, I'm a bit confused - looks like you have everything to get it done - and it's simple. But let me try to answer your question. Here is the code from my C# project where I extend app's token with my comments in case you are not familiar with C# languages and classes:
string currentToken = "token from somewhere";
// WebClient is used to send GET request to the given URL
// and receive the response
using (var req = new System.Net.WebClient())
{
// create URL string and fill it in with data (app Id, secret, and current token)
var extendTokenUrl = string.Format(
"https://graph.facebook.com/oauth/access_token?client_id={0}&client_secret={1}&grant_type=fb_exchange_token&fb_exchange_token={2}",
FB_APP_ID,
FB_APP_SECRET,
currentToken);
// send GET request and download the response
var response = req.DownloadString(extendTokenUrl);
// if all is good, response will be a string which looks like this:
// access_token=<<THE TOKEN GOES HERE>>
var newToken = response.Substring("access_token=".Length);
// now save newToken in your DB INSTEAD of currentToken -
// so all calls will be made with extended token
SaveTokenInDB(newToken);
}
hope that helps, and translating this into Java should be straightforward.
I am working on facebook android application but there is one problem i am facing
i am using the following example
Android/Java -- Post simple text to Facebook wall?
so the problem is that everything works here fine, the dialogs etc etc but When it open the screen to upload Walla Message that i have setted up here
try
{
System.out.println("*** IN TRY ** ");
Bundle parameters = new Bundle();
parameters.putString("message", "this is a test");// the message to post to the wall
facebookClient.dialog(this, "stream.publish", parameters, this);// "stream.publish" is an API call
}
catch (Exception e)
{
// TODO: handle exception
System.out.println(e.getMessage());
}
It does not show me my Message written in the dialog. Whats the problem with that
can anybody Guide me please..
Thanks alot.
Message has been ignored. You can read about it here: https://developers.facebook.com/docs/reference/dialogs/feed/
This field will be ignored on July 12, 2011 The message to prefill the text field that the user will type in. To be compliant with Facebook Platform Policies, your application may only set this field if the user manually generated the content earlier in the workflow. Most applications should not set this.
Use this code , it working for me :
Bundle parameters = new Bundle();
parameters.putString("message",sharetext.getText().toString());// the message to post to the wall
//facebookClient.dialog(Jams.this, "stream.publish", parameters, this);// "stream.publish" is an API call
facebookClient.request("me/feed", parameters, "POST");
Hope it helps..
Edited:
public class FacebookActivity implements DialogListener
{
private Facebook facebookClient;
private LinearLayout facebookButton;
public FacebookActivity(Context context) {
facebookClient = new Facebook();
// replace APP_API_ID with your own
facebookClient.authorize(Jams.this, APP_API_ID,
new String[] {"publish_stream", "read_stream", "offline_access"}, this);
}
#Override
public void onComplete(Bundle values)
{
if (values.isEmpty())
{
//"skip" clicked ?
}
// if facebookClient.authorize(...) was successful, this runs
// this also runs after successful post
// after posting, "post_id" is added to the values bundle
// I use that to differentiate between a call from
// faceBook.authorize(...) and a call from a successful post
// is there a better way of doing this?
if (!values.containsKey("post_id"))
{
try
{
Bundle parameters = new Bundle();
parameters.putString("message",sharetext.getText().toString());// the
message to post to the wall
//facebookClient.dialog(Jams.this, "stream.publish", parameters,
this);// "stream.publish" is an API call
facebookClient.request("me/feed", parameters, "POST");
sharetext.setText("");
Toast.makeText(Jams.this,"Message posted
successfully.",Toast.LENGTH_SHORT).show();
}
catch (Exception e)
{
// TODO: handle exception
// System.out.println(e.getMessage());
}
}
}
#Override
public void onError(DialogError e)
{
return;
}
#Override
public void onFacebookError(FacebookError e)
{
return;
}
#Override
public void onCancel()
{
return;
}
}