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

Flutter:如何从Google Drive恢复或下载SQLite数据库

解决Flutter从Google Drive恢复SQLite数据库备份的问题

要实现从Google Drive下载备份文件并替换本地SQLite数据库,你需要完成关闭本地数据库连接、下载Drive文件内容、覆盖本地数据库文件这几个核心步骤。以下是完善后的可运行代码:

import 'dart:io';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart' as p;
import 'package:google_sign_in/google_sign_in.dart' as sign_in;
import 'package:googleapis/drive/v3.dart' as drive;
import 'package:http/http.dart' as http;

class GoogleAuthClient extends http.BaseClient {
  final Map<String, String> _headers;
  final http.Client _client = http.Client();

  GoogleAuthClient(this._headers);

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    request.headers.addAll(_headers);
    return _client.send(request);
  }
}

Future<void> _downloadFile(String fileName, String fileId) async {
  final googleSignIn = sign_in.GoogleSignIn.standard(scopes: [drive.DriveApi.driveScope]);
  final sign_in.GoogleSignInAccount? account = await googleSignIn.signIn();
  final authHeader = await account?.authHeaders;

  if (authHeader == null) {
    throw Exception("用户未完成登录或授权");
  }

  var client = GoogleAuthClient(authHeader);
  var driveApi = drive.DriveApi(client);

  var databasesPath = await getDatabasesPath();
  var dbPath = p.join(databasesPath, 'my_database.db');
  
  // 1. 先关闭本地数据库连接(必须确保无活跃数据库操作)
  try {
    await closeDatabase(dbPath);
  } catch (e) {
    // 数据库未打开时忽略该错误
  }

  // 2. 从Google Drive获取文件媒体流
  final media = await driveApi.files.get(fileId, downloadOptions: drive.DownloadOptions.fullMedia);
  
  // 3. 将流写入本地数据库文件
  final file = File(dbPath);
  final sink = file.openWrite();
  
  await for (final chunk in media as Stream<List<int>>) {
    sink.add(chunk);
  }
  
  await sink.close();
  
  // 可选:验证恢复结果
  final db = await openDatabase(dbPath);
  final tableCount = await db.rawQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table'");
  print("恢复完成,本地数据库表数量:${tableCount.first.values.first}");
  await db.close();
}

需要留意的细节:

  • 必须关闭数据库连接:如果本地数据库处于活跃状态,直接覆盖文件会触发IO错误,所以要先关闭所有关联的数据库实例。
  • 流式写入避免内存溢出:大文件下载时用流逐块写入,不会一次性占用过多内存。
  • 异常兜底:实际开发中要补充网络错误、文件写入失败等场景的捕获处理,给用户明确的提示。
  • 权限校验:确保authHeader不为空,避免未授权状态下执行后续操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:05:15