The question:
I”m following this Tutorial but so far I can’t make it work, though this is from a year ago or so…
I’m using androidStudo 1.2.2 and FacebookSDK 4.
I want a simple login into facebook using a custom button, like the one shown in this image:
Now, in the example from the tutorial I’m having problems with the Session
variable, it says it cannot resolve it, neither getActivity()
Has naybody tried this on FacebookSDK4.0?
Is that a correct approach or maybe there is something more updated?
Thanks in advance!
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
Step 1:
First add FrameLayout and make facebook button visibility=”gone” and add your custom button.
Don’t forgot to put xmlns:facebook="http://schemas.android.com/apk/res-auto"
in your main layout.
<FrameLayout
android:id="@+id/FrameLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<com.facebook.login.widget.LoginButton
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<Button
android:id="@+id/fb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#416BC1"
android:onClick="onClick"
android:text="FaceBook"
android:textColor="#ffffff"
android:textStyle="bold" />
</FrameLayout>
Step 2:
Initialize FacebookSdk
in onCreate
before inflecting layout.
FacebookSdk.sdkInitialize(this.getApplicationContext());
Step 3: add this into your java file.
callbackManager = CallbackManager.Factory.create();
fb = (Button) findViewById(R.id.fb);
loginButton = (LoginButton) findViewById(R.id.login_button);
List < String > permissionNeeds = Arrays.asList("user_photos", "email",
"user_birthday", "public_profile", "AccessToken");
loginButton.registerCallback(callbackManager,
new FacebookCallback < LoginResult > () {@Override
public void onSuccess(LoginResult loginResult) {
System.out.println("onSuccess");
String accessToken = loginResult.getAccessToken()
.getToken();
Log.i("accessToken", accessToken);
GraphRequest request = GraphRequest.newMeRequest(
loginResult.getAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {@Override
public void onCompleted(JSONObject object,
GraphResponse response) {
Log.i("LoginActivity",
response.toString());
try {
id = object.getString("id");
try {
URL profile_pic = new URL(
"http://graph.facebook.com/" + id + "/picture?type=large");
Log.i("profile_pic",
profile_pic + "");
} catch (MalformedURLException e) {
e.printStackTrace();
}
name = object.getString("name");
email = object.getString("email");
gender = object.getString("gender");
birthday = object.getString("birthday");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields",
"id,name,email,gender, birthday");
request.setParameters(parameters);
request.executeAsync();
}
@Override
public void onCancel() {
System.out.println("onCancel");
}
@Override
public void onError(FacebookException exception) {
System.out.println("onError");
Log.v("LoginActivity", exception.getCause().toString());
}
});
Step 4:
Don’t forget to add following code.
@Override
protected void onActivityResult(int requestCode, int responseCode,
Intent data) {
super.onActivityResult(requestCode, responseCode, data);
callbackManager.onActivityResult(requestCode, responseCode, data);
}
Step 5:
Set your custom button click to FacebookLogin button click.
public void onClick(View v) {
if (v == fb) {
loginButton.performClick();
}
}
Step 6:
For programmatically logout use this.
LoginManager.getInstance().logOut();
Step 7: you can find user logged in or not by profile.
profile = Profile.getCurrentProfile().getCurrentProfile();
if (profile != null) {
// user has logged in
} else {
// user has not logged in
}
Method 2
IMO part of the selected answer is kind of work-around not the proper solution.
So what needs to be changed to make it proper is the following:
-
Get rid of “com.facebook.login.widget.LoginButton” from your XML
<com.facebook.login.widget.LoginButton android:id="@+id/login_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" />
-
Get rid of all references to the “LoginButton” in your Java code
-
Use Facebook’s “LoginManager” class which is there for that purpose as follows:
@Override protected void onCreate(Bundle savedInstanceState) { // Some code callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback( callbackManager, new FacebookCallback < LoginResult > () { @Override public void onSuccess(LoginResult loginResult) { // Handle success } @Override public void onCancel() { } @Override public void onError(FacebookException exception) { } } ); } public void onClick(View v) { if (v == fb) { LoginManager.getInstance().logInWithReadPermissions( this, Arrays.asList("user_photos", "email", "user_birthday", "public_profile") ); } } // this part was missing thanks to wesely @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); callbackManager.onActivityResult(requestCode, resultCode, data); }
Method 3
This is very simple.
Add a button in the layout file like
<Button
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Login with facebook"
android:textColor="#ffff"
android:layout_gravity="center"
android:textStyle="bold"
android:onClick="fbLogin"
android:background="@color/colorPrimary"/>
And in the onClick place the LoginManager’s registercallback() method
Becuse the this method automatically executes.
like:
public void fbLogin(View view)
{
// Before Edit:
// LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("user_photos", "email", "public_profile", "user_posts" , "AccessToken"));
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("user_photos", "email", "public_profile", "user_posts"));
LoginManager.getInstance().logInWithPublishPermissions(this, Arrays.asList("publish_actions"));
LoginManager.getInstance().registerCallback(callbackManager,
new FacebookCallback<LoginResult>()
{
@Override
public void onSuccess(LoginResult loginResult)
{
// App code
}
@Override
public void onCancel()
{
// App code
}
@Override
public void onError(FacebookException exception)
{
// App code
}
});
}
Have Fun
Method 4
(don’t have enough reputation to add a comment …)
I tried the @Shehabix’s answer, can’t receive callback until I add this
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
then it works fine.
Method 5
The Simple answer is add facebookButton.performClick()
inside cutomBtn.setOnClickListener
<!-- connect with Facebook -->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.facebook.login.widget.LoginButton
android:id="@+id/fb_connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textSize="@dimen/login_fb_font_size"
android:visibility="invisible" />
<LinearLayout
android:id="@+id/mfb_connect"
style="@style/facebook_button">
<ImageView
style="@style/login_connect_icon"
android:src="@drawable/ic_facebook" />
<TextView
style="@style/login_connect_text"
android:text="@string/login_connect_facebook" />
</LinearLayout>
</RelativeLayout>
…
private LoginButton fb_connect;
private LinearLayout mfb_connect;
…
// the button from facebook sdk
fb_connect = (LoginButton) findViewById(R.id.fb_connect);
// handle the click from my custom button to perfrom action click on facebook sdk button
mfb_connect = (LinearLayout) findViewById(R.id.mfb_connect);
mfb_connect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
fb_connect.performClick();
}
});
That will achieve this:
Method 6
i just call the facebook default button from my custom button and left every single line of code as documented. and bang it works successfully.
public class SignInFragment extends Fragment implements
FragmentChangeListener{
private Button facebook
private FirebaseAuth firebaseAuth;
private CallbackManager mCallBackManager;
private LoginButton loginButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_sign_in, container, false);
facebook = view.findViewById(R.id.facebookButton);
loginButton = view.findViewById(R.id.facebookBtn);
firebaseAuth = FirebaseAuth.getInstance();
facebook.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginButton.callOnClick();
}
});
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCallBackManager = CallbackManager.Factory.create();
loginButton.setFragment(SignInFragment.this);
loginButton.setPermissions("email","public_profile");
loginButton.registerCallback(mCallBackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
handleFacebookAccessToken(loginResult.getAccessToken());
}
@Override
public void onCancel() {
Toast.makeText(getContext(),"Is Cancelled",Toast.LENGTH_LONG).show();
}
@Override
public void onError(FacebookException error) {
Toast.makeText(getContext(),error.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
});
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mCallBackManager.onActivityResult(requestCode, resultCode, data);
}
private void handleFacebookAccessToken(AccessToken token) {
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
FirebaseUser user = firebaseAuth.getCurrentUser();
startActivity(new Intent(getContext(),MainActivity.class));
} else {
// If sign in fails, display a message to the user.
Toast.makeText(getContext(), task.getException().getMessage(),
Toast.LENGTH_SHORT).show();
}
}
});
}
}
Method 7
Complementing the answers by Harvi and Shehabix, I would suggest to add this method as this registers the authentication in Firebase Auth.
This method should be called inside “On Success” of LoginManager
.
private void handleFacebookAccessToken(AccessToken token) {
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//Toast.makeText(MainActivity.this, "Autenticando",Toast.LENGTH_SHORT).show();
} else {
// If sign in fails, display a message to the user.
Toast.makeText(MainActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
//updateUI(null);
}
}
});
}
Method 8
try this
// Facebook Button
LoginButton loginButton = findViewById(R.id.loginbtn);
// Your Custom Button
binding.fbBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loginButton.callOnClick();
}
});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0