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
相关产品推荐
相关产品推荐

