Reputation: 366
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).
Upvotes: 2
Views: 1873
Reputation: 366
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));
}
Upvotes: 2