问题描述
我一直想将 Google O 身份验证添加到我的 Xamarin.Forms 应用程序中,但 Xamarin.Android 部分导致了问题。 根据 YouTube 教程,我包含了所需的库并包含了必要的代码(见下文)。
对于 API,我使用 Google Firebase 和 Google Cloud Platform(需要获取我的 API 密钥)。 将我的应用程序安装到设备上时,无论是物理设备还是模拟设备,登录过程在接下来的 3-5 天内都能正常工作。我可以选择一个谷歌帐户并进行身份验证。 然而,the login screen will be stuck loading after that time.
有时,不经常,API 会返回
Status{statusCode=INTERNAL_ERROR,resolution=null}(请阅读下面我尝试过的内容)
我用于流程的库:
使用 Android.Gms.Auth.Api;
使用 Android.Gms.Auth.Api.SignIn;
使用 Android.Gms.Common;
使用 Android.Gms.Common.Apis;
使用Android.OS;
预期行为:
与往常一样,Google 登录弹出窗口会出现并自动登录用户(以防他们过去已经选择了帐户)或显示可用帐户并继续对用户进行身份验证。 This is how it should look like,sorry for the German 出了什么问题:
登录视图确实会弹出,但它只是继续加载。只有重新安装整个应用才能帮助修复它。
我尝试过的:
如上所述,我有时会得到
状态{statusCode=INTERNAL_ERROR,resolution=null}
回来了。 我已经研究了这个错误,并发现我的 android 应用程序的无效或不存在的 SHA1 密钥可能是原因。 我检查了 Firebase 并添加了我的调试和发布密钥库。
值得一提的:
- 登录程序始终在启动应用程序时进行。不管是否登录。这可能是一个原因,但我不知道我应该使用什么替代方案。也许存储 IdToken 并使用它直到它过期?
- 为了验证用户服务器端,我同时请求了 Email 和 IdToken。
- 我使用已弃用的 Android.Gms.Common.Apis
GoogleManager.cs
public class GoogleManager : java.lang.Object,IGoogleManager,Googleapiclient.IConnectionCallbacks,Googleapiclient.IOnConnectionFailedListener
{
public Action<GoogleUser,string> _onLoginComplete;
public static Googleapiclient _googleapiclient { get; set; }
public static GoogleManager Instance { get; private set; }
Context _context;
public GoogleManager()
{
_context = global::Android.App.Application.Context;
Instance = this;
}
public void Login(Action<GoogleUser,string> onLoginComplete)
{
GoogleSignInoptions gso = new GoogleSignInoptions.Builder(GoogleSignInoptions.DefaultSignIn).RequestIdToken("my_stuff.apps.googleusercontent.com")
.Requestemail()
.Build();
_googleapiclient = new Googleapiclient.Builder((_context).ApplicationContext)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(Auth.GOOGLE_SIGN_IN_API,gso)
.AddScope(new Scope(Scopes.Profile))
.Build();
_onLoginComplete = onLoginComplete;
Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(_googleapiclient);
((MainActivity)Forms.Context).StartActivityForResult(signInIntent,1);
_googleapiclient.Connect();
}
public void logout()
{
var gsoBuilder = new GoogleSignInoptions.Builder(GoogleSignInoptions.DefaultSignIn).Requestemail();
GoogleSignIn.GetClient(_context,gsoBuilder.Build())?.SignOut();
_googleapiclient.disconnect();
}
public void OnAuthCompleted(GoogleSignInResult result)
{
if (result.IsSuccess)
{
GoogleSignInAccount accountt = result.SignInAccount;
_onLoginComplete?.Invoke(new GoogleUser()
{
Name = accountt.Givenname,Email = accountt.Email,ID = accountt.Id,IdToken = accountt.IdToken,},string.Empty);
}
else
{
_onLoginComplete?.Invoke(null,AppResources.error_this_didnt_work_text);
}
}
public void OnConnected(Bundle connectionHint)
{
}
public void OnConnectionSuspended(int cause)
{
_onLoginComplete?.Invoke(null,"Canceled!");
}
public void OnConnectionFailed(ConnectionResult result)
{
_onLoginComplete?.Invoke(null,result.ErrorMessage);
}
来自 MainActivity.cs 的 OnActivityResult
protected override void OnActivityResult(int requestCode,Result resultCode,Android.Content.Intent data)
{
base.OnActivityResult(requestCode,resultCode,data);
if (requestCode == 1)
{
GoogleSignInResult result = Auth.GoogleSignInApi.GetSignInResultFromIntent(data);
Console.WriteLine("LOGIN RESULT" + result.Status + result.SignInAccount);
GoogleManager.Instance.OnAuthCompleted(result);
}
}
希望有人有答案。如果您有什么需要了解的,请告诉我
解决方法
如果您收到错误代码 8 (INTERNAL_ERROR
),请在开发控制台中仔细检查您的应用注册。请注意,每个注册的 Android 客户端都由(包名称、Android 签名证书 SHA-1)对唯一标识。如果您的调试和生产环境有多个包名称/签名证书,请确保注册每一对。验证:
-
打开 Credentials page 并选择您的项目
-
确保 每对都有一个 Android 类型的 OAuth 2.0 客户端 ID。创建一个 Android 客户端的新 OAuth 2.0 客户端 ID,从下拉列表中选择
New Credentials
->OAuth2 Client ID
,选择 Android 并 在那里输入您的包名称/签名证书指纹。
要获取您的签名密钥证书 SHA-1:
标准调试键
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
其他(自定义)键
keytool -list -v -keystore $YOUR_KEYSTORE_LOCATION