I had my app posting feed stories to facebook fine until yesterday.
Now it stopped working and sends this error in the callback:
"com.facebook.FacebookException: could not construct request body"
This comes from:
response.getError();
Strangely the sample app from facebook stopped working and is now reporting the same error, I'm quite sure I didn't change anything on it.
Here's the sample app function:
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
return;
}
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i("publishStory",
"JSON error "+ e.getMessage());
}
Toast.makeText(getApplicationContext(), postId,Toast.LENGTH_LONG).show();
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
Can anyone help please!
Thank you in advance.
Now it works...I've turned off my computer and Eclipse during the night and now restarted
I guess it was some bug in the compiler.
Related
My current success response is this:
{"status":"success","message":"msg here"}
with code 200
And my error response is this:
{"status":"failure","message":"There was a validation error","errors":{"shippingAddress":{"phoneNumber":"Please enter a valid phone number"}}}
with code 400
my problem is the code below is not working because it always go inside onFailure()
if (response.isSuccessful()) {
// do something
} else if (response.code() == 400) {
Gson gson = new Gson();
ErrorPhone message = null;
if (response.errorBody() != null) {
message = gson.fromJson(response.errorBody().charStream(), ErrorPhone.class);
}
if (message != null) {
Toast.makeText(context, message.getErrors().getShippingAddress().getPhoneNumber(), Toast.LENGTH_LONG).show();
} else {
String errors = "";
try {
JSONObject jObjError = new JSONObject(response.errorBody().string());
errors = jObjError.getJSONObject("errors").getJSONObject("shippingAddress").getString("phoneNumber");
} catch (JSONException | IOException e) {
e.printStackTrace();
}
if (!errors.equals("")) {
Toast.makeText(context, errors, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, response.message(), Toast.LENGTH_LONG).show();
}
}
}
and inside onFailure i cant listen to errorBody to handle the response
Use Retrofit interface called onResponse and place your code there. As Retrofit uses two different callback methods for the two possible outcomes of a network requests: either a failure or a successful request. Retrofit will call the appropriate callback method depending on the result. If the request was successful, Retrofit will also pass you the response of the server.
For more view this link:https://square.github.io/retrofit/2.x/retrofit/retrofit2/Callback.html and https://futurestud.io/tutorials/java-basics-for-retrofit-callbacks that will help you more to learn about retrofit Call-backs
I've been trying to set up a google login for my app.
I followed the tutorial here:
https://developers.google.com/identity/sign-in/android/start-integrating
I did everything. I can sign in sign in and sign out.
Then I added an Async task to get a token, which it seems to successfully retrieve. It is implemented as follows:
private class GetIdTokenTask extends AsyncTask<Void, Void, String> {
private static final String SERVER_CLIEdNT_ID = "749433126040-ca4gfj7ucuh0m2suo3230u03o3d7doni.apps.googleusercontent.com";
#Override
protected String doInBackground(Void... params) {
String accountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
Account account = new Account(accountName, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
String scopes = "audience:server:client_id:" + SERVER_CLIEdNT_ID; // Not the app's client ID.
try {
return GoogleAuthUtil.getToken(getApplicationContext(), account, scopes);
} catch (IOException e) {
Log.e(TAG, "Error retrieving ID token.", e);
return null;
} catch (GoogleAuthException e) {
Log.e(TAG, "Error retrieving ID token. Google exception", e);
return null;
}
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "ID token: " + result);
if (result != null) {
idToken = result;
Toast.makeText(context, "token is " + result, Toast.LENGTH_LONG).show();
} else {
// There was some error getting the ID Token
// ...
Toast.makeText(context, "token is null", Toast.LENGTH_LONG).show();
}
}
}
So after running the method and getting the token, I then run the generic firebase code to connect to Firebase (having already set up a google app, put the client ID in firebase, enabled it etc.) I got the code from https://www.firebase.com/docs/android/guide/login/google.html
And implemented it as follows:
public void loginFireBase() {
Firebase ref = new Firebase("https://boiling-fire-944.firebaseio.com");
ref.authWithOAuthToken("google", idToken, new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
// the Google user is now authenticated with your Firebase app
Toast.makeText(context, "user succesfully authenticated with firebase", Toast.LENGTH_LONG).show();
Toast.makeText(context, idToken, Toast.LENGTH_LONG).show();
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
///////THIS IS THE PART WHERE THE ERROR IS GENEREATED FROM//////////
Log.v("firebase problem", firebaseError.toString());
Toast.makeText(context, "I'm an authenticated error" + "id Token was " + idToken, Toast.LENGTH_LONG).show();
}
});
}
}
So ultimately, I login, I get a token, and then pass it to the firebase authWithOAuthToken method, and then I get the error:
FirebaseError: Invalid authentication credentials provided.
Can anyone see any problems in my code? I have a feeling the token is not valid but can't find a way to check its validity.
Tell me if you need me to post more, I was trying to keep it brief.
Thanks to anybody who can help !
Whenever I need to authenticate with Firebase on Android, I go back to the Firebase Android login demo. Here's how that app gets the OAuth token for Google authentication:
String scope = String.format("oauth2:%s", Scopes.PLUS_LOGIN);
token = GoogleAuthUtil.getToken(
GoogleOAuthActivity.this,
Plus.AccountApi.getAccountName(mGoogleApiClient),
scope);
It looks like you're getting the cross-client id for the user, which is not a valid OAuth token.
Update (20160308): nowadays I instead look at the FirebaseUI library, which includes this functionality and is more up to date.
In my case i was having this error message in Firebase/Crash
the solution was run this line:
rm $HOME/Library/Preferences/com.google.SymbolUpload*
this was happening because previously already had generated the ServiceAccount.json file and restart the credentials needed
I'm working on an android app for a Facebook group. Using the graph API, I can easily post a text status but when I upload a photo, it returns error saying
(#100) The picture is not properly formatted
If I use the same code to post to my wall, the photo upload works fine.
Is this an API restriction or there is a separate approach to upload a photo to a group?
Following is my code:
Request photoRequest = Request.newUploadStagingResourceWithImageRequest(session, bitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (mProgress != null && mProgress.isShowing())
mProgress.dismiss();
if (response.getError() == null) {
Toast.makeText(NewPostActivity.this, "Successfully shared on the group", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(NewPostActivity.this, "Facebook sharing error: " + response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Bundle params = photoRequest.getParameters();
if(message != null) {
params.putString("message", message);
}
if(imageBytes != null) {
params.putByteArray("picture", imageBytes);
}
photoRequest.setParameters(params);
photoRequest.setHttpMethod(HttpMethod.POST);
photoRequest.setGraphPath(Constants.URL_FEEDS);
photoRequest.executeAsync();
EDIT
I'm using Graph API v2.3
It does seem to be possible to post a photo in a group.
You can make a POST request to photos edge from the following paths:
/{group_id}/photos
When posting to this edge, a Photo will be created.
Link
Return type
Struct {
id: numeric string,
post_id: token with structure: Post ID,
}
It seems like the POST request to /<group-id>/feed doesn't allow to upload a photo (which otherwise works for /me/feed). I finally got this working with the /<group-id>/photos edge as suggested. Following is my code - hoping that it helps some:
Request photoRequest = Request.newUploadStagingResourceWithImageRequest(session, bitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (mProgress != null && mProgress.isShowing())
mProgress.dismiss();
if (response.getError() == null) {
Toast.makeText(NewPostActivity.this, "Successfully shared on the group", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(NewPostActivity.this, "Facebook sharing error: " + response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
}
});
Bundle params = photoRequest.getParameters();
if(message != null) {
params.putString("message", message);
photoRequest.setGraphPath(Constants.URL_FEEDS);
}
if(imageBytes != null) {
params.putByteArray("picture", imageBytes);
photoRequest.setGraphPath(Constants.URL_PHOTOS);
}
photoRequest.setParameters(params);
photoRequest.setHttpMethod(HttpMethod.POST);
photoRequest.executeAsync();
I started work with Vkontakte android SDK, and doing it well). I made authorization, and got userFirstName, userLastName and userPhoto. But I have no idea how get user wall, or user posts from user wall. It should be similar, and I see response #2 in logcat, but I don't really know how parse it???
//Prepare request for userName and photo
final VKRequest request1 = VKApi.users().get(VKParameters.from(VKApiConst.FIELDS, "photo_100, contacts"));
//Prepare request for userWall
final VKRequest request2 = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID));
//Parallel executing requests
VKBatchRequest batch = new VKBatchRequest(request1, request2);
batch.executeWithListener(new VKBatchRequest.VKBatchRequestListener() {
#Override
public void onComplete(VKResponse[] responses) {
super.onComplete(responses);
//Work with responses
//*****
//UserName and photo response
//*****
VKApiUserFull user = ((VKList<VKApiUserFull>) responses[0].parsedModel).get(0);
Ion.with(ivUserPhoto).placeholder(R.drawable.ic_launcher)
.error(R.drawable.ic_launcher)
.load(user.photo_100);
tvUserName.setText(user.first_name + " " + user.last_name);
//********
//Wall response similar sa userResponse...
//********
VKApiPost mPost = ((VKList<VKApiPost>) responses[1].parsedModel).get(0);
Log.e("post name", mPost.toString());
}
#Override
public void onError(VKError error) {
//Error;
}
});
Here right code, tnx Dreddik <-- vk android sdk developer.
VKRequest request2 = VKApi.wall().get(VKParameters.from(VKApiConst.OWNER_ID, VKSdk.getAccessToken().userId, VKApiConst.EXTENDED, 1));
request2.executeWithListener(new VKRequestListener() {
#Override
public void onError(VKError error) {
}
#Override
public void onComplete(VKResponse response) {
VKList<VKApiPost> posts = (VKList<VKApiPost>) response.parsedModel;
VKApiPost post = posts.get(0);
Log.d("Post:", post.toString());
}
});
In my app I am using Parse.com and Facebook login, and the Facebook login is working and I am now trying to save the email of the user who signed. I am doing this like this:
Request.newMeRequest(ParseFacebookUtils.getSession(), new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
String email = user.getProperty("email").toString();
Log.i(TAG, email);
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.put("email", email);
currentUser.saveInBackground();
}
}
}).executeAsync()
But then when I run I get java.lang.NullPointerException at this line currentUser.put("email", email); But I log email before this and it is not null and I have a email attribute in my User class on parse, so Im not sure why this?
Here the code that comes before to set up the FB Login you should need it and it is working but just in case.
public void onLoginClick(View v) {
progressDialog = ProgressDialog.show(LoginActivity.this, "", "Logging in...", true);
final List<String> permissions = Arrays.asList("public_profile", "email");
// NOTE: for extended permissions, like "user_about_me", your app must be reviewed by the Facebook team
// (https://developers.facebook.com/docs/facebook-login/permissions/)
ParseFacebookUtils.logIn(permissions, this, new LogInCallback() {
#Override
public void done(ParseUser user, ParseException err) {
progressDialog.dismiss();
if (user == null) {
Log.d(TAG, "Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew()) {
Log.d(TAG, "User signed up and logged in through Facebook!");
showSelectSchoolActivity();
} else {
Log.d(TAG, "User logged in through Facebook!");
showMainActivity();
}
}
});
Thanks for the help :)
for checking the response you should always use (err==null) as the condition for success. Only after you have recieved the response from the server and err==null then you can check for current user. You should also have a check for when err!=null. Then get the error message from the err.getCode() and check what the error code is.