How to create and save Json file to Google Drive with the googleapis in flutter

1,307

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));

}
Share:
1,307
Alex Totolici
Author by

Alex Totolici

I want to be the best at what I'm doing

Updated on December 13, 2022

Comments

  • Alex Totolici
    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).