我已经在我的Android应用中成功实现了使用Firebase身份验证的Google登录。
如您所见,我已经用我的帐户登录,它显示在Firebase控制台上。
功能firebaseAuthWithGoogle在用户使用Google登录后使用Firebase对其进行身份验证:
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, 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");
final FirebaseUser user = mFirebaseAuth.getCurrentUser();
//This is to connect to the http server and save the user data in my MySql database
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(LoginActivity.this, new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String userToken = instanceIdResult.getToken();
String uid = user.getUid();
String name = user.getDisplayName();
String email = user.getEmail();
String profileUrl = user.getPhotoUrl().toString();
String coverUrl = "";
UserInterface userInterface = ApiClient.getApiClient().create(UserInterface.class);
Call<Integer> call = userInterface.signin(new LoginActivity.UserInfo(uid,name,email,profileUrl,coverUrl,userToken));
call.enqueue(new Callback<Integer>() {
@Override
public void onResponse(Call<Integer> call, Response<Integer> response) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this,"Login succesfull AFTER API CALL",Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this,MainActivity.class));
finish();
}
@Override
public void onFailure(Call<Integer> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show();
}
});
}
});
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithCredential:failure", task.getException());
}
// ...
}
});
}
功能firebaseAuthWithGoogle的另一件事是:连接到HTTP Apache服务器,并通过以下代码段将用户信息保存在MySQL users table中:
//This is to connect to the http server and save the user data in my MySql database FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(LoginActivity.this, new OnSuccessListener<InstanceIdResult>() { @Override public void onSuccess(InstanceIdResult instanceIdResult) { String userToken = instanceIdResult.getToken(); String uid = user.getUid(); String name = user.getDisplayName(); String email = user.getEmail(); String profileUrl = user.getPhotoUrl().toString(); String coverUrl = ""; UserInterface userInterface = ApiClient.getApiClient().create(UserInterface.class); Call<Integer> call = userInterface.signin(new LoginActivity.UserInfo(uid,name,email,profileUrl,coverUrl,userToken)); call.enqueue(new Callback<Integer>() { @Override public void onResponse(Call<Integer> call, Response<Integer> response) { progressDialog.dismiss(); Toast.makeText(LoginActivity.this,"Login succesfull AFTER API CALL",Toast.LENGTH_SHORT).show(); startActivity(new Intent(LoginActivity.this,MainActivity.class)); finish(); } @Override public void onFailure(Call<Integer> call, Throwable t) { progressDialog.dismiss(); Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show(); } }); } }); }
因此,在对用户进行成功认证]之后,对服务器的调用将失败,并且此行显然已执行:
和okhttp用作http主体拦截器到请求如下:Toast.makeText(LoginActivity.this,"Login failed AFTER API CALL",Toast.LENGTH_SHORT).show();
我将Retrofit
用作http客户端
出现在模拟器上之后,我在日志上显示了此内容:ApiClient.java
public static Retrofit getApiClient(){ HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient httpClient = new OkHttpClient.Builder() .addInterceptor(httpLoggingInterceptor) .build(); if(retrofit==null){ retrofit = new Retrofit.Builder().baseUrl(BASE_URL) .client(httpClient) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } }
因此,在Toast文本“登录失败后API CALL”
D/OkHttp: --> POST http://10.0.2.2/friendster/public/app/login Content-Type: application/json; charset=UTF-8 Content-Length: 413 D/OkHttp: {"CoverUrl":"","email":"[email protected]","name":"Ahmed Ghrib","profileUrl":"https://lh6.googleusercontent.com/-S8l_5gZaXJ8/AAAAAAI/AAAAAAAAAAA/ACHi3rfObo6-Ta-wxrMUvcAZ8Yg/s96-c/photo.jpg","uid":"YACACYYDcGVr26N8OHuTuQlQqvU2","userToken":"ecxdtFaKldI:APA91bHb1PAA5hU6i1oMqnSsDXXkAaXNb6dynyaYmhU_soHTWmLXud6REjCpqTjsGpgdBh1NMYUqAr3SaTUWapN4v73zkvyYD2f3yegUP3H38eeU_JtH7NOSMKbF4U"} D/OkHttp: --> END POST (413-byte body) W/e.myapplicatio: Verification of okhttp3.internal.http.ExchangeCodec okhttp3.internal.connection.RealConnection.newCodec$okhttp(okhttp3.OkHttpClient, okhttp3.Interceptor$Chain) took 134.353ms D/OkHttp: <-- HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to 10.0.2.2 not permitted by network security policy
所以我发现这是导致错误的地方:
CLEARTEXT与10.0.2.2的通信是网络安全所不允许的政策
经过StackOverflow之后,我发现需要创建此文件:
src / main / res / xml / network_security_config.xml
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">api.example.com(to be adjusted)</domain> </domain-config> </network-security-config>
并将其添加到清单中:
<application --- android:networkSecurityConfig="@xml/network_security_config">
已经用Postman测试了我的数据库,我确定问题出在我的Android项目中。我认为这应该已经解决了问题。但是,我仍然有完全相同的问题。我仍然在日志中收到此错误:
CLEARTEXT与10.0.2.2的通信是网络安全所不允许的政策
我已成功在我的Android应用中使用Firebase身份验证实现了google登录。如您所见,我已经用我的帐户登录,它显示在Firebase控制台上。函数...
src / main / res / xml / network_security_config.xml