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

如何在Xamarin中使用现有AccessToken调用Google APIs上传AppData?

嘿,我来帮你搞定这个GoogleCredential创建失败的问题!结合Xamarin.Auth和Google APIs的常见踩坑点,给你几个关键的解决方向:

问题分析与解决方案

首先看你给出的代码片段,应该是在从Xamarin.Auth保存的Account中提取AccessToken创建GoogleCredential时出了问题,大概率和权限范围、令牌有效性或者API客户端初始化方式有关,下面一步步来排查:

1. 先确认登录时请求的OAuth权限范围是否正确

Google Drive的AppData文件夹需要特定的权限,你在Xamarin.Auth初始化登录流程时,必须包含https://www.googleapis.com/auth/drive.appdata这个scope,不然就算拿到AccessToken,调用AppData相关API也会权限不足,导致Credential验证失败。示例代码如下:

var auth = new OAuth2Authenticator(
    clientId: "你的Google客户端ID",
    scope: "https://www.googleapis.com/auth/drive.appdata", // 这个scope必须加!
    authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/v2/auth"),
    redirectUrl: new Uri("com.googleusercontent.apps.xxxxxx:/oauth2redirect"));

如果需要同时访问其他Drive资源,还可以追加其他scope,比如https://www.googleapis.com/auth/drive.file,但drive.appdata是必须的。

2. 正确从AccessToken创建GoogleCredential并初始化Drive服务

你的代码可能没处理完整,正确的初始化流程应该是这样的,我补全并标注了关键细节:

var store = AccountStore.Create();
var savedAccount = store.FindAccountsForService(GoogleDriveBackup.Auth.Constants.AppName).FirstOrDefault();

if (savedAccount != null && !string.IsNullOrEmpty(savedAccount.Properties["access_token"]))
{
    // 从AccessToken创建Credential,同时指定需要的scope
    var credential = GoogleCredential.FromAccessToken(savedAccount.Properties["access_token"])
        .CreateScoped(new[] { "https://www.googleapis.com/auth/drive.appdata" });

    // 初始化Drive服务客户端
    var service = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "你的应用名称"
    });

    // 接下来就可以用service上传AppData了,示例:上传一个json文件到AppData文件夹
    var fileMetadata = new Google.Apis.Drive.v3.Data.File()
    {
        Name = "app_backup.json",
        Parents = new List<string>() { "appDataFolder" } // 必须指定这个父文件夹标识
    };

    // 替换成你的AppData内容流
    using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("你的应用数据内容")))
    {
        var uploadRequest = service.Files.Create(fileMetadata, stream, "application/json");
        uploadRequest.Fields = "id"; // 指定只返回文件ID,减少响应数据
        var uploadResponse = uploadRequest.Execute();
        Console.WriteLine("AppData上传成功!文件ID: " + uploadResponse.Id);
    }
}

这里要注意:

  • Xamarin.Auth默认会把AccessToken存在access_token这个键下,你可以调试确认savedAccount.Properties["access_token"]的值是否有效;
  • 如果AccessToken过期,你需要在登录时请求offline_access scope拿到RefreshToken,这样才能自动刷新令牌,避免后续操作失败。

3. 检查AccessToken的有效性

如果创建Credential时直接报错,建议先验证一下AccessToken是否有效:

var httpClient = new HttpClient();
var validationResponse = await httpClient.GetAsync($"https://www.googleapis.com/oauth2/v3/tokeninfo?access_token={savedAccount.Properties["access_token"]}");
if (validationResponse.IsSuccessStatusCode)
{
    var validationContent = await validationResponse.Content.ReadAsStringAsync();
    // 解析这个内容可以看到令牌的权限、过期时间等信息,帮你排查问题
}
else
{
    // 令牌无效,需要重新登录或者用RefreshToken刷新
}

4. 确保NuGet包版本兼容

不同版本的Google API客户端库和Xamarin.Auth可能存在兼容性问题,建议使用最新的稳定版NuGet包:

  • Google.Apis.Drive.v3
  • Google.Apis.Auth
  • Xamarin.Auth

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:31:44