I have been battling this problem for hours now and I seem to get nowhere with it. So, I have successfully asked the users to login using Facebook to my android app.
Once they are logged in, I get the access token (a string value) and then use it to make a Request to Facebook to fetch a Page's Posts. Here is how I do that whole process.
public void setupFacebook()
{
Session.openActiveSession(this, true, new Session.StatusCallback()
{
// callback when session changes state
#Override
public void call(Session mSession, SessionState state, Exception exception) {
if (mSession.isOpened() && mSession != null)
{
facebookAccessToken = mSession.getAccessToken();
Log.d("ACCESSTOKEN", facebookAccessToken);
fetchPagePosts(facebookAccessToken, mSession);
}
}
});
}
public void fetchPagePosts(String token, Session session)
{
Request.Callback callback = new Request.Callback()
{
#Override
public void onCompleted(Response response)
{
Log.d("RESPONSE", "ERROR"+response.getError());
Log.d("RESPONSE", ""+response);
}
};
String endpoint = String.format("https://graph.facebook.com/"+pageId+"/posts?access_token=%s", facebookAccessToken);
Log.d("ENDPOINT", endpoint);
Request request = new Request(session, endpoint, null, HttpMethod.GET, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
The interesting part here is that when I copy the url from my Logcat (what I called endpoint) and paste to my browser, it works perfectly fine.
When I run my code on my tablet though, it returns the ErrorCode 190 and HttpStatus 400.
According to Facebook's documentation, it could be one of several things;
Access token is invalid
It is expired
The user has changed their password or
The user has logged out of their account
The user has revoked access to their account by your app!
I am stuck here because I have tested the same URL on the browser and it returns the json data I need. It just fails when am running it in android code.
If anyone has suggestions, please help me - will be truly thankful for your help.
Thank you in advance.
You could try using the Simple Facebook Android library instead of the Facebook SDK https://github.com/sromku/android-simple-facebook, its a lot simpler.
Related
I am trying to get Auth0 integrated into my web app which uses the spark-java framework.
The problem is while the authentication works perfectly, including the callback(I see the new user created on Auth0's website and my website gets redirected), I can't access the logged in user info. I've tried several methods like SessionUtils.getAuth0User(request.raw()) and none of them are working.
For example in the provided tutorial here: https://github.com/auth0-samples/auth0-servlet-sample/tree/master/01-Login
they access the logged in user info like so:
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
final Auth0User user = SessionUtils.getAuth0User(req);
if (user != null) {
req.setAttribute("user", user);
}
req.getRequestDispatcher("/WEB-INF/jsp/home.jsp").forward(req, res);
}
I've tried doing something similar with Spark but since the get works a bit differently in Spark I do this:
port(Integer.valueOf(System.getenv("PORT")));
staticFileLocation("/spark/template/freemarker");
String clientId = System.getenv("AUTH0_CLIENT_ID");
String clientDomain = System.getenv("AUTH0_DOMAIN");
get("/", (request, response) ->
{
Map<String, Object> attributes = new HashMap<>();
Auth0User user = SessionUtils.getAuth0User(request.raw());
if(user != null) {
attributes.put("user", user);
attributes.put("loggedIn" , true);
}
else
attributes.put("loggedIn" , false);
attributes.put("clientId" , clientId);
attributes.put("clientDomain" , clientDomain);
return new ModelAndView(attributes, "index.ftl");
}, new FreeMarkerEngine());
The code is always reporting the user as null even though the user is created and stored in the database and the signin works properly with no runtime or console errors. The other methods I tried I replaced the line where I set the user variable and wrote the following.
Alternate Method 1:
Auth0User user = (Auth0User) request.session().attribute("auth0User");
Here auth0User is the same string literal Auth0 uses in their implementation of SessionUtils as shown in their source code referenced here: https://github.com/auth0/auth0-java-mvc-common/blob/master/src/main/java/com/auth0/SessionUtils.java
Alternate Method 2:
Auth0User user = (Auth0User) request.raw().getUserPrincipal();
In addition this is my javascript code running client side for the authentication:
var lock = new Auth0Lock('${clientId}', '${clientDomain}', {
auth: {
redirectUrl: 'http://localhost:5000/build',
responseType: 'code',
params: {
scope: 'openid user_id name nickname email picture'
}
}
});
$(document).ready(function()
{
$('.signup').click(function()
{
doSignup();
});
});
function doSignup() {
lock.show();
}
I have no idea why user is being evaluated to null every time and I would love some feedback on what I'm doing wrong. Thanks.
In order for you to get a non null user instance from SessionUtils.getAuth0User(req) some piece of code must first call SessionUtils.setAuth0User. This should be done when you receive confirmation that the user authenticated with success.
In the auth0-servlet-sample you were using as reference this is done by configuring an Auth0ServletCallback that will handle requests performed to /callback endpoint. Since the Auth0ServletCallback calls (see code below) the set user for you, in the servlet example you can then get the user with success.
protected void store(final Tokens tokens, final Auth0User user, final HttpServletRequest req)
{
SessionUtils.setTokens(req, tokens);
SessionUtils.setAuth0User(req, user);
}
At the moment the available samples (auth0-servlet-sample, auth0-servlet-sso-sample, auth0-spring-mvc-sample, auth0-spring-security-api-sample and auth0-spring-security-mvc-sample) don't include one for spark-java so I can't refer you to any sample.
In order to solve this you have to include additional logic to process the result of the authentication operation in your spark-java application and in case of success call the SessionUtils.setAuth0User yourself if you then want to use the corresponding SessionUtils.getAuth0User method.
For general guidance on integrating a web application with Auth0 check Integrating a Web App with Auth0.
I would like to use restfb to post to one of my pages. I want to post as the page itself, not as an user posting to the page's wall.
This is the code I'm using:
public class App {
//user token for accessing the page as admin
private static final String INITIAL_ACCESS_TOKEN = "#";
public static void main(String[] args) throws Exception {
restfb();
}
public static void restfb() throws Exception {
DefaultFacebookClient fbClient;
Connection myAccounts;
fbClient = new DefaultFacebookClient(INITIAL_ACCESS_TOKEN, Version.VERSION_2_5);
myAccounts = fbClient.fetchConnection("me/accounts", Account.class);
String pageToken = null;
//retrieve the page token
for(Object a : myAccounts.getData()) {
Account account = (Account)a;
if("MyPage".equals(account.getName())) {
pageToken = account.getAccessToken();
break;
}
}
System.out.println(pageToken); //not null here
//post to the page
fbClient = new DefaultFacebookClient(pageToken, Version.VERSION_2_5);
//"me" should refer to the page itself..?
fbClient.publish("me/feed", FacebookType.class, Parameter.with("message", "Aloha! ;)"));
}
}
I get error
Received Facebook error response of type OAuthException: (#200) The user hasn't authorized the application to perform this action (code 200, subcode null)
I already visited this url:
https://www.facebook.com/dialog/oauth?client_id=###&redirect_uri=###&scope=manage_pages,publish_actions,user_actions:pagealias&response_type=code
It asked me to give permissions to my app to post and manage my pages, and I granted them.
The application is not public, as it is a test application I want to use for development (so I didn't ask for the Review).
What am I missing? Which other permission does the app need in order to work and properly post?
You should request the publish_pages permission to post as page.
https://developers.facebook.com/docs/facebook-login/permissions#reference-publish_pages
I have an Android app with parse login with Facebook that works just fine… I´m building a new version of the app in which the app has the capability to do share to a Facebook Page, as the page. This is my code:
this is the code to request the list of pages the user manages
final Session session = Session.getActiveSession();
List<String> PERMISSIONS = Arrays.asList("publish_actions, publish_pages, manage_pages,user_about_me");
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(activity,PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
new Request(
session,
"/me/accounts",
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */}
Once selected a page, the link share is done by:
final String id = json_obj.getString("id");
String token = json_obj.getString("access_token");
Date date = new Date(3600);
List<String> PERMISSIONS = Arrays.asList("publish_actions, publish_pages, manage_pages,user_about_me");
final Bundle params = new Bundle();
params.putString("message", message);
params.putString("access_token", token);
params.putString("link", link);
params.putString("picture", image);
new Request(
session,
"/" + id + "/feed",
params,
HttpMethod.POST,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */}
The code works just fine, the link is posted to a Facebook Page, as the facebook page.
The problem comes when the user logs off and tries to log back in with facebook. Parse log in fails, without error message, and returns a null user. The weird thing is that this keeps on happening the particular device where the code was run, matter what user tries to login, or even if we uninstall the app and install a previous version which was working perfectly.
So far I’ve tested with three different devices and I get the same result, everything works fine before doing the facebook share as page. After that, no matter what user or what version of the app I run, the parse facebook log in fails returning a null user.
Ok, I found the what the issue WAS...
They way I had the code, it would ask for facebook permissions several times, and that would somehow mess up the user on facebook
I am trying to setup login on my app using facebook. Currently I have the SDK working fine, it authenticates and I can accession user information and then I start an Intent to my activity. (not sure if this is what I should be doing)
Now I am wondering what the workflow is for this is to authenticate with my RestAPI.
I can post the facebook_id to my server and add to my users database but I then read that I should be using the AccessToken, but how do I know if this is the correct AccessToken for that user?
What should be the flow here? Where should I be posting to the server and what should I be posting for every request in every Activity?
Here is my code I currently have.
private Session.StatusCallback statusCallback = new Session.StatusCallback() {
#Override
public void call(final Session session, SessionState sessionState, Exception e) {
if (sessionState.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser graphUser, Response response) {
if (graphUser != null) {
Log.w(TAG, graphUser.getFirstName() + ' ' + graphUser.getId());
Log.w(TAG, session.getAccessToken() + ' ' + session.getExpirationDate());
Intent intent = new Intent(LoginActivityFragment.this, MainActivity.class);
startActivity(intent);
}
}
}).executeAsync();
} else if (sessionState.isClosed()) {
}
}
};
You should use the user ID as the unique identifier. The access token can change under many situations (updated permissions, user log in/out, etc), and should not be used to identify someone. The user ID will remain stable within your app.
You can send the access token along with the ID to your server, perhaps to make some FB requests from the server side, but that's a separate issue.
i think the context of my question is clear enough, but i would like to specifiy that i'm using a OAuth for Web Application, so I used this Example provided by Google: OAuth 2.0 for WebApplication
I understood that i have to create (for example in the same class (extended by HttpServlet)) a doGet method (obviously in Override) to obtain the correct flow to authorize the user with own scopes, so something like this:
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//This is a class to obtain the Current Google User's ID
UserService userService = UserServiceFactory.getUserService();
String userId = userService.getCurrentUser().getUserId();
String url = getAuthorizationUrl(userId);
if(req.getParameter("code")!=null){
try {
String authorizationCode = req.getParameter("code");
getCredentials(authorizationCode);
} catch (CodeExchangeException | NoRefreshTokenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//the next page (my homePage)
resp.sendRedirect("/home");
}
else{
resp.sendRedirect(url);
}
}
This successfully work, if you look at the provided method 'getCredential(authorizationCode)' it shows 2 method: storeCredential and getStoredCredential.
The first method works perfectly and i can see the refreshToken and accessToken strings in my Datastore indeed.
The problem is to build the getStoredCredential method, because it returns a Credential object and i don't know to write it. I show you the beginning of the method but i don't know how to carry on.
static Credential getStoredCredentials(String googlePlusUserId) {
// TODO: Implement this method to work with your database. Instantiate a new
// Credential instance with stored accessToken and refreshToken.
//These methods of my Class correctly get the tokens (already debugged)
String refreshToken = UserManager.getStoredRefreshToken(googlePlusUserId);
String accessToken = UserManager.getStoredAccessToken(googlePlusUserId);
//How can i continue here? :-( to return Credential with correct parameters?
//......
//......
//......
//......
}
Does this method works forever?
Because in Google OAuth Playgroung there is a checkbox that says: "Auto-refresh the token before it expires" (i think in 3600 seconds). So, i don't think that completing my getStoredCredential get my App working correctly...I think that is only useful for get always the last token...So in this case i can never obtain a new accessToken using the Stored RefreshToken.
Does anyone can help me please? Maybe with a simple method that refresh the old AccessToken.