如何解决在 Firebase Auth 中合并 facebook 和 google 用户
在我的应用中,我最近通过邮件、Facebook 和谷歌添加了登录信息。
我可以切换提供商:Facebook-> Firebase 上的 Google 但不能更改 Google -> Facebook 我必须补充一点,我不会为不同的提供者做单独的帐户,以合并它们。 有人可以帮助我完成此链接凭据吗?
package com.company.altasnotas.fragments.login_and_register;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.viewmodelProvider;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.company.altasnotas.MainActivity;
import com.company.altasnotas.R;
import com.company.altasnotas.fragments.home.HomeFragment;
import com.company.altasnotas.viewmodels.LoginFragmentviewmodel;
import java.util.Map;
import java.util.Objects;
import com.facebook.Accesstoken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInApi;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInoptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Googleapiclient;
import com.google.android.gms.common.api.internal.Googleapimanager;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.ktx.Firebase;
import static android.content.ContentValues.TAG;
public class LoginFragment extends Fragment {
private static final int RC_SIGN_IN = 120;
GoogleSignInClient mGoogleSignInClient;
CallbackManager callbackManager;
LoginFragmentviewmodel model;
LoginButton facebookLoginButton;
FirebaseAuth mAuth;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_login,container,false);
mAuth = FirebaseAuth.getInstance();
model = new viewmodelProvider(requireActivity()).get(LoginFragmentviewmodel.class);
EditText email_editext = view.findViewById(R.id.login_email_edittext);
EditText password_editext = view.findViewById(R.id.login_password_edittext);
view.findViewById(R.id.login_w_mail_btn).setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
model.login((MainActivity) requireActivity(),email_editext.getText().toString().toLowerCase().trim(),password_editext.getText().toString().toLowerCase().trim());
}
});
view.findViewById(R.id.jump_to_register_btn).setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
requireActivity().getSupportFragmentManager().beginTransaction().addToBackStack(null).replace(R.id.main_fragment_container,new RegisterFragment()).commit();
}
});
// Initialize Facebook Login button
FacebookSdk.sdkInitialize(getContext());
callbackManager = CallbackManager.Factory.create();
facebookLoginButton = view.findViewById(R.id.fb_new_login_button);
facebookLoginButton.setReadPermissions("email","public_profile");
facebookLoginButton.setFragment(this);
// Callback registration
facebookLoginButton.registerCallback(callbackManager,new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Accesstoken token = loginResult.getAccesstoken();
Log.d("Dziala ","Token: "+ token.getUserId());
handleFacebookAccesstoken(loginResult.getAccesstoken());
}
@Override
public void onCancel() {
Log.d("Facebook","Login Canceled");
}
@Override
public void onError(FacebookException exception) {
Log.d("Facebook","Login error: "+exception.toString());
}
});
ImageButton fb_btn = view.findViewById(R.id.login_fb_btn);
fb_btn.setonClickListener(v -> facebookLoginButton.performClick());
//Google Auth
ImageButton google_btn = view.findViewById(R.id.login_google_btn);
// Configure Google Sign In
GoogleSignInoptions gso = new GoogleSignInoptions.Builder(GoogleSignInoptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestemail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(getContext(),gso);
google_btn.setonClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signIn();
}
});
return view;
}
@Override
public void onStart() {
super.onStart();
FirebaseUser user = mAuth.getCurrentUser();
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.updateUI(user);
}
private void handleFacebookAccesstoken(Accesstoken token) {
MainActivity mainActivity = (MainActivity) getActivity();
mAuth = FirebaseAuth.getInstance();
String TAG="Facebook";
Log.d(TAG,"handleFacebookAccesstoken:" + token);
AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
if(mAuth.getCurrentUser()!=null){
mAuth.getCurrentUser().linkWithCredential(credential).addOnCompleteListener(mainActivity,new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Toast.makeText(mainActivity,"Link Facebook success",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(mainActivity,"Link Facebook fail",Toast.LENGTH_SHORT).show();
}
}
});
}else {
mAuth.signInWithCredential(credential).addOnCompleteListener(mainActivity,new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
FirebaseUser user = mAuth.getCurrentUser();
mainActivity.updateUI(user);
int count = mainActivity.getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < count; i++) {
mainActivity.getSupportFragmentManager().popBackStack();
}
Toast.makeText(mainActivity,"Sign Facebook success",Toast.LENGTH_SHORT).show();
BottomNavigationView bottomNavigationView = mainActivity.findViewById(R.id.main_nav_bottom);
bottomNavigationView.setSelectedItemId(R.id.nav_home_item);
mainActivity.getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container,new HomeFragment()).commit();
} else {
Toast.makeText(mainActivity,"Sign Facebook fail",Toast.LENGTH_SHORT).show();
mainActivity.updateUI(null);
}
}
});
}
}
private void signIn() {
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
startActivityForResult(signInIntent,RC_SIGN_IN);
}
@Override
public void onActivityResult(int requestCode,int resultCode,Intent data) {
super.onActivityResult(requestCode,resultCode,data);
callbackManager.onActivityResult(requestCode,data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
if(task.isSuccessful()){
try {
// Google Sign In was successful,authenticate with Firebase
GoogleSignInAccount account = task.getResult(ApiException.class);
Log.d(TAG,"firebaseAuthWithGoogle:" + account.getId());
firebaseAuthWithGoogle(account.getIdToken());
} catch (ApiException e) {
// Google Sign In Failed,update UI appropriately
Log.w(TAG,"Google sign in Failed",e);
}
}else{
Log.w(TAG,task.getException().toString());
}
}
}
private void firebaseAuthWithGoogle(String idToken) {
MainActivity mainActivity = (MainActivity) getActivity();
AuthCredential credential = GoogleAuthProvider.getCredential(idToken,null);
if(mAuth.getCurrentUser()!=null){
mAuth.getCurrentUser().linkWithCredential(credential).addOnCompleteListener(mainActivity,new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Toast.makeText(mainActivity,"Link google succeded!",Toast.LENGTH_SHORT).show();
FirebaseUser user = mAuth.getCurrentUser();
mainActivity.updateUI(user);
BottomNavigationView bottomNavigationView = mainActivity.findViewById(R.id.main_nav_bottom);
bottomNavigationView.setSelectedItemId(R.id.nav_home_item);
int count = mainActivity.getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < count; i++) {
mainActivity.getSupportFragmentManager().popBackStack();
}
mainActivity.getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container,new HomeFragment()).commit();
}else{
Toast.makeText(mainActivity,"Link google Failed!",Toast.LENGTH_SHORT).show();
}
}
});
}else {
mAuth.signInWithCredential(credential).addOnCompleteListener(mainActivity,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
Log.d(TAG,"signInWithCredential:success");
Toast.makeText(mainActivity.getApplicationContext(),"Sign Google success",Toast.LENGTH_SHORT).show();
FirebaseUser user = mAuth.getCurrentUser();
mainActivity.updateUI(user);
BottomNavigationView bottomNavigationView = mainActivity.findViewById(R.id.main_nav_bottom);
//We shouldnt Could go back so if i were transfering to another activity
// I should add finish(); at the end of code after starting another activity
bottomNavigationView.setSelectedItemId(R.id.nav_home_item);
int count = mainActivity.getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < count; i++) {
mainActivity.getSupportFragmentManager().popBackStack();
}
mainActivity.getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container,new HomeFragment()).commit();
} else {
// If sign in fails,display a message to the user.
Log.w(TAG,"signInWithCredential:failure",task.getException());
Toast.makeText(mainActivity.getApplicationContext(),"Sign Google Failed",Toast.LENGTH_SHORT).show();
mainActivity.updateUI(null);
}
}
});
}
}
}
另外我想补充一点,我尝试了一种使用 Googleapiclient 的方法,但它告诉我无论我选择什么 ID,它始终被程序使用
解决方法
对于任何有同样问题的人:
这里的问题是 Google 切换了不应该发生的提供商。 这是一个很长时间的错误,他们没有修复它。他们称之为功能哈哈。
这就是为什么我花了两天时间来解决这个问题。感谢谷歌
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。