You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Maui中Google认证模拟器正常但真机失败的排查方案

解决.NET Maui中Xamarin.GooglePlayServices.Auth真机Google认证失败问题

问题描述

我在.NET Maui应用中使用Xamarin.GooglePlayServices.Auth实现Google认证功能,该功能在模拟器上运行正常,但在真实设备上认证失败:SilentSignInAsync抛出异常,手动调用AuthenticateAsync也无法完成认证。

已尝试操作:检查真机上Google Play服务权限;验证WebApiKey和请求的权限范围正确;尝试真机调试但未捕获到具体错误。

相关代码:

public partial class GoogleAuthService
{
    public static Activity _activity;
    public static GoogleSignInOptions _gso;
    public static GoogleSignInClient _googleSignInClient;

    private TaskCompletionSource<GoogleUserDTO> _taskCompletionSource = new TaskCompletionSource<GoogleUserDTO>();

    private Task<GoogleUserDTO> GoogleAuthentication
    {
        get => _taskCompletionSource.Task;
    }

    public GoogleAuthService()
    {
        _activity = Platform.CurrentActivity;

        _gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
            .RequestIdToken(WebApiKey)
            .RequestEmail()
            .RequestId()
            .RequestProfile()
            .Build();

        _googleSignInClient = GoogleSignIn.GetClient(_activity, _gso);

        MainActivity.ResultGoogleAuth += MainActivity_ResultGoogleAuth;
    }

    public Task<GoogleUserDTO> AuthenticateAsync()
    {
        _taskCompletionSource = new TaskCompletionSource<GoogleUserDTO>();

        _activity.StartActivityForResult(_googleSignInClient.SignInIntent, 9001);

        return GoogleAuthentication;
    }

    private void MainActivity_ResultGoogleAuth(object sender, (bool Success, GoogleSignInAccount Account) e)
    {
        if (e.Success)
        {
            try
            {
                var currentAccount = e.Account;

                _taskCompletionSource.SetResult(
                    new GoogleUserDTO
                    {
                        Email = currentAccount.Email,
                        FullName = currentAccount.DisplayName,
                        TokenId = currentAccount.IdToken,
                        UserName = currentAccount.GivenName,
                    });
            }
            catch (Exception ex)
            {
                _taskCompletionSource.SetException(ex);
            }
        }
    }

    public async Task<GoogleUserDTO> GetCurrentUserAsync()
    {
        try
        {
            var user = await _googleSignInClient.SilentSignInAsync();
            return new GoogleUserDTO
            {
                Email = user.Email,
                FullName = $"{user.DisplayName}",
                TokenId = user.IdToken,
                UserName = user.GivenName
            };
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    public Task LogoutAsync() => _googleSignInClient.SignOutAsync();
}

排查与解决步骤

  • 检查Google Cloud Console配置

    • 确保已将真机应用的SHA-1指纹添加到Google Cloud Console的OAuth 2.0客户端ID中。模拟器使用调试密钥的SHA-1,真机若使用不同签名密钥(如发布密钥或其他调试密钥),必须对应添加。
    • 确认客户端ID类型为Android,且包名与真机应用的包名完全一致。
  • 替换弃用的StartActivityForResult
    .NET Maui中StartActivityForResult已被弃用,改用RegisterForActivityResult处理认证结果,修改后的核心代码:

    private readonly ActivityResultLauncher<Intent> _signInLauncher;
    
    public GoogleAuthService()
    {
        _activity = Platform.CurrentActivity;
    
        _gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
            .RequestIdToken(WebApiKey)
            .RequestEmail()
            .RequestId()
            .RequestProfile()
            .Build();
    
        _googleSignInClient = GoogleSignIn.GetClient(_activity, _gso);
    
        // 用ActivityResultLauncher替代事件监听
        _signInLauncher = _activity.RegisterForActivityResult(new ActivityResultContracts.StartActivityForResult(), result =>
        {
            if (result.ResultCode == Result.Ok && result.Data != null)
            {
                var task = GoogleSignIn.GetSignedInAccountFromIntent(result.Data);
                if (task.IsSuccessful)
                {
                    var account = task.Result;
                    _taskCompletionSource.SetResult(new GoogleUserDTO
                    {
                        Email = account.Email,
                        FullName = account.DisplayName,
                        TokenId = account.IdToken,
                        UserName = account.GivenName
                    });
                }
                else
                {
                    _taskCompletionSource.SetException(task.Exception);
                }
            }
            else
            {
                _taskCompletionSource.SetException(new Exception("认证被取消或失败"));
            }
        });
    }
    
    public Task<GoogleUserDTO> AuthenticateAsync()
    {
        _taskCompletionSource = new TaskCompletionSource<GoogleUserDTO>();
        _signInLauncher.Launch(_googleSignInClient.SignInIntent);
        return _taskCompletionSource.Task;
    }
    

    移除原MainActivity.ResultGoogleAuth事件绑定,避免逻辑冲突。

  • 完善异常捕获与日志
    在GetCurrentUserAsync中捕获具体异常类型,精准定位问题:

    public async Task<GoogleUserDTO> GetCurrentUserAsync()
    {
        try
        {
            var user = await _googleSignInClient.SilentSignInAsync();
            return new GoogleUserDTO
            {
                Email = user.Email,
                FullName = $"{user.DisplayName}",
                TokenId = user.IdToken,
                UserName = user.GivenName
            };
        }
        catch (ApiException ex)
        {
            // 根据错误码判断原因,如SIGN_IN_REQUIRED需触发手动认证
            if (ex.StatusCode == GoogleSignInStatusCodes.SignInRequired)
            {
                return null;
            }
            Console.WriteLine($"SilentSignIn失败:{ex.Message},错误码:{ex.StatusCode}");
            return null;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"未知错误:{ex.Message}");
            return null;
        }
    }
    
  • 验证Google Play服务版本
    检查真机Google Play服务是否为最新版本,旧版本可能存在兼容性问题。可通过GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(_activity)检查状态,若返回非SUCCESS,提示用户更新。

  • 确认应用签名匹配
    确保真机安装的应用签名与Google Cloud Console中配置的SHA-1指纹一致:调试阶段用调试密钥库的SHA-1,发布版本用发布密钥库的SHA-1。

内容的提问来源于stack exchange,提问作者Vladyslav Malin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 09:25:15