How to create and save Json file to Google Drive with the googleapis in flutter
Found it:
class DriveHelper{
GoogleSignInAccount currentUser ;
// Specify the permissions required at login
GoogleSignIn _googleSignIn = new GoogleSignIn (
scopes: < String > [
DriveApi . DriveFileScope ,
],
);
static init(BuildContext buildContext)async{
DriveHelper driveHelper=DriveHelper();
driveHelper._googleSignIn.onCurrentUserChanged.listen(( GoogleSignInAccount account ) {
driveHelper.currentUser=account ;
} );
await driveHelper._googleSignIn.signInSilently ();
return driveHelper;
}
// google sign in
Future < Null > handleSignIn () async {
await _googleSignIn . signIn ();
}
Future handleSignOut()async{
await _googleSignIn.signOut();
}
// Upload a file to Google Drive.
Future uploadFile(BuildContext buildContext)async {
if(currentUser==null){
launchPage(buildContext, WelcomePage());
return;
}
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, DatabaseHelper.dataBaseName);
//
GoogleHttpClient client = GoogleHttpClient(await currentUser.authHeaders);
var api = new drive.DriveApi(client);
var localFile = new io.File(path);
var media = new drive.Media(localFile.openRead(), localFile.lengthSync());
drive.File driveFile = new drive.File()..title = DatabaseHelper.dataBaseName;
return (await api.files.insert(driveFile, uploadMedia: media,)).id;
}
// Upload a file to Google Drive.
Future deleteFile(BuildContext buildContext,drive.File file)async {
if(currentUser==null){
launchPage(buildContext, WelcomePage());
return;
}
//
GoogleHttpClient client = GoogleHttpClient(await currentUser.authHeaders);
var api = new drive.DriveApi(client);
await api.files.delete(file.id);
}
// Download a file from Google Drive.
Future downloadFile(BuildContext buildContext,drive.File file) async{
if(currentUser==null){
launchPage(buildContext, WelcomePage());
return false;
}
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, DatabaseHelper.dataBaseName);
performDriveRequest(
buildContext: buildContext,
file: io.File(path),
headers: await currentUser.authHeaders,
url: file.downloadUrl??'',
);
return true;
//
}
Future<List<File>> getAllFiles(BuildContext buildContext)async{
if(currentUser==null){
launchPage(buildContext, WelcomePage());
return [];
}
GoogleHttpClient client = GoogleHttpClient(await currentUser.authHeaders);
var api = new drive.DriveApi(client);
return (await api.files.list()).items;
}
Future performDriveRequest({@required BuildContext buildContext,@required io.File file,@required Map<String,String> headers,@required String url})async{
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.getUrl(Uri.parse(url));
headers.forEach((k,v){
request.headers.set(k, v);
});
HttpClientResponse response = await request.close();
if(response.statusCode==200){
var _downloadData = List<int>();
response.listen((d) => _downloadData.addAll(d),
onDone: () {
file.writeAsBytes(_downloadData).then((v){
showDistivityDialog(buildContext, actions: [getButton('Refresh', onPressed: (){
MyApp.dataModel=null;
DistivityRestartWidget.restartApp(buildContext);
})], title: 'Calendars and events downloaded', stateGetter: (ctx,ss){
return getText('Your calendars and your events from your last saved file from drive are now on your device');
});
});
}
);
}else{
return null;
}
}
}
class GoogleHttpClient extends IOClient {
Map<String, String> _headers;
GoogleHttpClient(this._headers) : super();
@override
Future<IOStreamedResponse> send(BaseRequest request) =>
super.send(request..headers.addAll(_headers));
@override
Future<Response> head(Object url, {Map<String, String> headers}) =>
super.head(url, headers: headers..addAll(_headers));
}
Comments
-
Alex Totolici over 1 year
So I have a Map<> of objects witch I want to save as a .json file in Google Drive using the googleapis plugin. But the documentation is soo poor and I just can't figure it out.
I've tried these tutorials/examples https://qiita.com/aoinakanishi/items/6ff8222847fcf934a64a(it's a Chinese one lol) https://github.com/dart-lang/googleapis_examples/blob/master/drive_upload_download_console/bin/main.dart
They have some pieces that work and some that don't
class GoogleDriveDatabase{ GoogleSignIn googleSignIn ; GoogleHttpClient client; drive.DriveApi api; String fileId = ""; static Future<GoogleDriveDatabase> init(BuildContext context) async{ GoogleDriveDatabase _googleDriveDatabase = GoogleDriveDatabase(); _googleDriveDatabase.googleSignIn = GoogleSignIn( scopes: < String > [ drive.DriveApi . DriveFileScope , ], ); GoogleSignInAccount googleSignInAccount = await _googleDriveDatabase.googleSignIn.signInSilently(); if(googleSignInAccount == null){ launchPage(context, WelcomePage()); return null; } Map authHeaders = await googleSignInAccount.authHeaders; _googleDriveDatabase.client = GoogleHttpClient(authHeaders); _googleDriveDatabase.api = drive.DriveApi(_googleDriveDatabase.client); return _googleDriveDatabase; } Future createDatabaseToDrive(String jsonFileName) async{ drive.File file = drive.File.fromJson({"name":jsonFileName}); drive.GeneratedIds generatedIds =await api.files.generateIds(space: "drive",count: 1); generatedIds.ids.forEach((f){ file.id = f; }); return api.files.create( file, ); } Future updateDbToDrive(Future<File> jsonFileFuture, String jsonFileName) async{ drive.File file = drive.File.fromJson({"name":jsonFileName}); file.id=jsonFileName; File jsonFile = await jsonFileFuture; //if it doesn't work catch the error on future return (api.files.update( file, jsonFileName, uploadMedia: drive.Media(jsonFile.openRead(),jsonFile.lengthSync()) )); } // Download a file from Google Drive. Future downloadFile(String jsonFileName)async { bool fileExists = false; var fileList = await api.files.list(); fileList.files.forEach((f)async{ var files = await api.files.list(); files.files.forEach((f){ fileId= f.id; fileExists = true; }); }); var file; if(!fileExists){ file = await createDatabaseToDrive( jsonFileName); }else{ file =await api.files.get(jsonFileName); } return client.readBytes(file.downloadUrl).then((bytes) { IOSink stream = new File(jsonFileName).openWrite()..add(bytes); return stream.close(); }); } } class GoogleHttpClient extends IOClient { Map<String, String> _headers; GoogleHttpClient(this._headers) : super(); @override Future<StreamedResponse> send(BaseRequest request) => super.send(request..headers.addAll(_headers)); @override Future<Response> head(Object url, {Map<String, String> headers}) => super.head(url, headers: headers..addAll(_headers)); }
For now i just want a method that i can pass my updated map object, turn it into a .json file and save or create it to drive, and another method to get the file and read it as a Map<> object(without knowing the id of the file, I just tried that by looping trough all the files as you've seen in the code snippet).