i have working code to get user info except the email. this is my request code:
private void requestLoginFb() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setPermissions(
Arrays.asList("basic_info", "email")).setCallback(
fbCallback));
} else {
Session.openActiveSession(act, true, fbCallback);
}
}
here where i get user info
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (null != user) {
C.trace("user name: " + user.getName());
C.trace("user gender: " + user.asMap().get("gender"));
}
}
});
my graph result no email:
GraphObject{graphObjectClass=Map, state={"id":"10000xxxxxxx","first_name":"xxxx","username":"xxxxxx","timezone":x,"locale":"en_US","link":"https:\/\/www.facebook.com\/xxxxxx","name":"xxxxx","last_name":"xxxxx","gender":"male","education":[{"type":"xxxx","school":{"id":"xxxxx","name":"xxxxx"}}],"updated_time":"xxxxxxx"}}
i'm concern about the way i put permission. then i put basic info and email on session. and i don't know if this the right way.
UPDATE
here screenshot while request to facebook. even there is a friend list that i don't put on permission. and on my graph, still no email there.
This is well known issue ..... for some accounts facebook don't wanna return email even when the code is correct. could you please try with other accounts?
I think you've added the permissions after being authorized once. So check out what all permissions you've provided to this app here by clicking on the Edit.
If you find that email permission is not set, then you can logout of the app/remove the app from the settings and then login again; so that you can be authorized again with the email permission included.
For getting email from facebook, try it something like below.
String email = user.asMap().get("email").toString();
Textview mEmail = (TextView) findViewById(R.id.textView1);
mEmail.setText(email);
By using this above code i am successfully able to get the email of facebbok user. Try it and let me know if you still face any problem.
Related
I would like to ask that is there any methods in Facebook SDK able to identify whether the user logged in in the Facebook Apps changed or not? Because I am using the AccessToken.CurrentAccessToken method to check whether user logged in before or not, but it won't update if user in Facebook Apps changed. Thanks!
Here is how I perform checking:
// Get the current access token if user logged in before
AccessToken objAccessToken = AccessToken.CurrentAccessToken;
// Check the token value, access token validity and data access validity
bool blnIsLoggedIn = objAccessToken != null && !objAccessToken.IsExpired && !objAccessToken.IsDataAccessExpired;
if (blnIsLoggedIn)
{
// If user logged in, direct perform to get user profile
GetFacebookUserProfile(objAccessToken, strUserProfileScopes);
}
else
{
// If user not logged in, perform login
LoginManager.Instance.LogIn(CurrentActivity, DefaultScopes);
}
private void GetFacebookUserProfile(AccessToken objAccessToken, string strUserProfileScopes)
{
GraphRequest objGraphRequest = GraphRequest.NewMeRequest(objAccessToken, new clsGraphJSONObjectCallback());
Bundle objParameters = new Bundle();
objParameters.PutString("fields", strUserProfileScopes);
objGraphRequest.Parameters = objParameters;
objGraphRequest.ExecuteAsync();
}
With reference to this link, I integrated the Uber sdk into my app.before that I registered my application in the Uber developer site got my client id and the client secret.
I added the below code in my application class:
UberSdk.initialize(this, "MY_CLIENT_ID");
UberSdk.setRedirectUri("MY_REDIRECT_URI");
UberSdk.setSandboxMode(true);
Then in my fragment:
oncreate():
accessTokenManager = new AccessTokenManager(getContext());
loginManager = new LoginManager(accessTokenManager);
List<Scope> scopes = new ArrayList<Scope>();
scopes.add(Scope.PROFILE);
scopes.add(Scope.RIDE_WIDGETS);
Date expirationTime = new Date(System.currentTimeMillis());
String token = "Token";
AccessToken accessToken = new AccessToken(expirationTime, scopes, token);
accessTokenManager.setAccessToken(accessToken);
Log.d("ttt", "accessToken: " + accessTokenManager.getAccessToken());
loginManager.loginWithScopes(getActivity(), scopes);
onActivityResult():
LoginCallback loginCallback = new LoginCallback() {
#Override
public void onLoginCancel() {
// User canceled login
Log.d("ttt", " User canceled login " );
Toast.makeText(getContext(), "User canceled login", Toast.LENGTH_SHORT).show();
}
#Override
public void onLoginError(#NonNull AuthenticationError error) {
// Error occurred during login
Log.d("ttt", "Error occurred during login" );
Toast.makeText(getContext(),"Error occurred during login",Toast.LENGTH_SHORT).show();
}
#Override
public void onLoginSuccess(#NonNull AccessToken accessToken) {
// Successful login! The AccessToken will have already been saved.
Log.d("ttt", "Successful login! " );
Toast.makeText(getContext(),"Successful login!",Toast.LENGTH_SHORT).show();
}
};
loginManager.onActivityResult(requestCode, resultCode, data, loginCallback);
I have no idea how to add redirect uri and from where I will get the redirect uri. And what is the actual use of it (searched a lot still not clear with what it does).
Once I click the Uber ride button it navigates to some loginactivity and a popup shows up saying "There was a problem authenticating you".
What I am doing wrong here?
Here's a great write up of what a Redirect URI is used for in Oauth 2.0. What's a redirect URI? how does it apply to iOS app for OAuth2.0?.
TLDR: Your application may exist on the web and for mobile app, and the redirect URI is the endpoint that is redirected back to after the flow is completed. For mobile clients, you could easily set your redirect URI to "http://localhost" in the Uber developer dashboard, since it doesn't have the same requirements as on the web.
We're investigating simplifying this further, so keep an eye out on our future releases!
No matter what I try, Facebook GraphUser user is alsways null. I am trying the following using Facebook SDK 3.23.0
loginButton
.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
#Override
public void onUserInfoFetched(GraphUser user) {
FragmentFour.this.user = user;
if (user != null) {
Log.d("Name",user.getName());
} else {
Log.d("Name","Not Logged in!!");
}
}
});
I have done with hash key and have successfully experimented Facebook samples in Facebook SDK using own created app id. But whenever I try above code i always get user as null. Please help.
I solved it by myself by adding
loginBtn.setReadPermissions("user_friends");
loginBtn.setFragment(this);
I've been using Parse for 3 months in my android app. Now I want to add email login and social sign ons (Facebook and Google+) in the app. I have successfully added email and fb login and the user can connect both or either one of email or facebook and the app would recognise the user.
e.g. If I login through email, then connect facebook, use the app on another device, login via facebook, the app would know it's the same user and would be customised for me and would show my data. And email also works.
I have added Google+ sign-in for Android but I am not able to connect the user's Google+ credentials with the logged in user.
Parse Users table has an authData field which gets the facebook auth data and would get Twitter as well as both of these sign ons are baked into Parse SDKs.
What should be the best thing to do for Google+? I'm confused about the db design as well as how to connect the user who signed in with Google+?
What if the user just logs in via Google+? How do I make a Parse User and authenticate the user on Parse?
I'm comfortable with cloud code and Android and would really appreciate some sort of help/instructions just pushing me in the correct direction. I have never used OAuth2 and with Parse login for email and Social Sign ons, I don't think I should get into it. But let me know if I'm wrong.
Thanks!
Update: I have read a lot of questions on Parse Questions and have checked out the become method plenty of times (because I kept thinking I'm missing something after reading that). Check this question - I'm currently in the same situation.
I have:
1. Implemented Google+ sign in.
2. Got access token using GoogltAuthUtil.
Stuck with:
3. How to link currently signed in Parse user after the user signs in with Google+?
4. How to create a new Parse User if Google+ was the user's first (and only ) login choice?
This seems to be similar with
How to create a parse _User account from a Android Google token?
Following is my answer in that thread:
1. New User
The flow is as below:
User authorizes and a token is acquired
We create a new user with a random password
You can create a ParseUser using following code inside the newChooseAccountIntent() method that return email.
ParseUser user = new ParseUser();
user.setUsername(mEmail);
user.setPassword(randomPassword);
user.setEmail(mEmail);
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
// Hooray! Let them use the app now.
} else {
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
2. Returning User
This is the where most of people stuck, as I researched over the Internet. The flow is as below:
User authorizes and the app gets a token
We pass this token to Cloud Code to validate. We need to check if this token is signed by Google and if it is meant for us (android-developers (2013)).
After you can verify that the token is valid, you can query for the user in Cloud Code using Parse.Cloud.useMasterKey() method and return the session key by using getSessionToken() method on the query result.
Use the session key to save login state on disk by calling becomeInBackground method
To validate the token, you can send Parse.Cloud.httprequest to this endpoint: https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=. This is instructed in Google Identity Documentation. You will receive data as below:
{
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"email": "billd1600#gmail.com",
"at_hash": "X_B3Z3Fi4udZ2mf75RWo3w",
"email_verified": "true",
"aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"iat": "1433978353",
"exp": "1433981953"
}
Things need to compare are "aud", "azp" and "email" which are translated as audience, authorized party and email.
To query for the current user on Cloud Code:
var query = new Parse.Query(Parse.User);
query.equalTo("email",mEmail);
query.first({
success: function(user) {
// Use user..getSessionToken() to get a session token
},
error: function(user, error) {
//
},
useMasterKey: true
});
Note: Make sure you have following scope so that the email will show up when you check on Cloud Code: https://www.googleapis.com/auth/plus.profile.emails.read
There's a question about this on Parse's questions. It's right here and I'm pretty sure it answers your questions.
https://parse.com/questions/google-plus
It links to the parse blog, that has some workarounds on this.
It says that you can add any login into ParseUser. You would be doing something like this:
Parse.User.become("session-token-here").then(function (user) {
// The current user is now set to user.
}, function (error) {
// The token could not be validated.
});
Another site where you should take a look:
https://parse.com/tutorials/adding-third-party-authentication-to-your-web-app
This last one is official and has an example code
void createNewGPlusUser(final String email, String name) {
final ParseUser user = new ParseUser();
user.setUsername(email);
user.setPassword("my pass");
user.put("any other variable in User class", "value");
user.setEmail(email);
user.put("name", name);
signInParseUser(user, email);
}
void signInParseUser(final ParseUser user, final String email) {
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
Log.d("TAG", "Created user");
// Hooray! Let them use the app now.
login(email);
} else {
Log.d("TAG", "Failed Creating user");
e.printStackTrace();
// Sign up didn't succeed. Look at the ParseException
// to figure out what went wrong
}
}
});
}
void login(final String email) {
ParseUser.logInInBackground(email, "my pass", new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
// Hooray! The user is logged in.
Log.d("TAG", "Login successful");
} else {
// Signup failed. Look at the ParseException to see what happened.
}
}
});
}
To do so, I have used the following code
ParseUser.becomeInBackground(ParseUser.getCurrentUser().getSessionToken(), new LogInCallback() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (parseUser != null) {
parseUser.setUsername(userEmail);
//firstName and lastName I am getting from Person class of google plus api
parseUser.put("FirstName", firstName);
parseUser.put("LastName", lastName);
parseUser.saveInBackground();
ParseUtils.verifyParseConfiguration(context);
ParseUtils.subscribeWithUsername(strEmail);
Intent successIntent = new Intent(context, OurServicesActivity.class);
startActivity(successIntent);
overridePendingTransition(R.animator.fade_in, R.animator.fade_out);
finish();
} else {
Log.e(TAG, e.getMessage());
Utilities.showToast(context, "Something occurred");
}
}
});
Let me know if it helps or if you have used something else.
Try this
ParseUser.becomeInBackground("session-token-here", new LogInCallback() {
public void done(ParseUser user, ParseException e) {
if (user != null) {
// The current user is now set to user.
} else {
// The token could not be validated.
}
}
})
I'm using facebook login at my app, and I was able to get neccesery information about logged in user (first and last name, id. gender etc..) so I can open a specific profile with that id. since I'm working with the latest facebook SDK I'm not able to get the user id.
I've noticed that there are few changes in this SDK but the issue that the only thing that I'm missing now is the user id. I can get the other information except the id - it gives me a wrong id (17 digits).
When I check it through the browser (using graph instead www) I can see that the user id including only 10 digits.
Here's the code:
private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
#SuppressWarnings("deprecation")
RequestAsyncTask request = Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (session == Session.getActiveSession()) {
if (user != null) {
user_ID = user.getId();//user id
profileName = user.getName();//user's profile name
token = session.getAccessToken();
.
.
.
}
else
{
.
.
}
}
}
});
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
The issue is the upgrade of facebook SDK to graph API v2.0.
Facebook gives a unique ID for users, changing between apps, which means that the given ID is not the original user id.
Facebook reference:
Changes from v1.0 to v2.0
App-scoped User IDs: To better protect people's information, when
people log into a version of your app that has been upgraded to use
Graph API v2.0, Facebook will now issue an app-scoped ID rather than
that person's orginal ID.
My solution is using the browser and not facebook application.
The url should look like this:
http://www.facebook.com/GivenUserId
and the code:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/"+userid)));