Upload file to google drive with googleapis in Background (Flutter)

784

For those who still need an answer to this question:

We have to use the method: signInSilently() that attempts to login using previously authenticated account without any user interaction. Suitable to use in background services.

Future<void> upload(context) async {
    GoogleSignInAccount? account = await googleSignIn.signInSilently();
    if (account == null) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
        content: Text("Not logged in"),
      ));
      return;
    }
    final authHeaders = await account.authHeaders;
    final authenticateClient = GoogleAuthClient(authHeaders);
    final driveApi = drive.DriveApi(authenticateClient);

    final Stream<List<int>> mediaStream =
        Future.value([104, 105]).asStream().asBroadcastStream();
    var media = drive.Media(mediaStream, 5);
    var driveFile = drive.File();
    driveFile.name = "hello_world.txt";
    final result = await driveApi.files.create(driveFile, uploadMedia: media);
    print("Upload result: ${result.name}");
}
Share:
784
Santo Shakil
Author by

Santo Shakil

Nothing special about me.

Updated on December 22, 2022

Comments

  • Santo Shakil
    Santo Shakil over 1 year

    I can upload files to google drive with googleapis in the foreground but I need to upload files in the background in my flutter app. I tried to upload with workmanager but it doesn't work. Here is some necessary part of the code for this post of my app:

    ...
    @override
      void initState() {
        WidgetsFlutterBinding.ensureInitialized();
        Workmanager.initialize(callbackDispatcher, isInDebugMode: true);
        Workmanager.registerPeriodicTask("1", "simplePeriodicTask",
            existingWorkPolicy: ExistingWorkPolicy.replace,
            frequency: Duration(hours: 1),
            initialDelay:
                Duration(seconds: 5),
            constraints: Constraints(
              networkType: NetworkType.connected,
            ));
        super.initState();
        login()
      }
    ...
    

    ...

    This is for background task:

    ...
    void callbackDispatcher() {
      Workmanager.executeTask((task, inputData) {
        login();
        _HomeState().uploadFileL();
        print('Background Services are Working!');
        return Future.value(true);
      });
    }
    ...
    

    ...

    This is for upload file:

    ...
    Future<void> uploadFileL() async {
        final filename = 'Location.db';
        final gFile = ga.File();
        gFile.name = filename;
        final dir = await getExternalStorageDirectory();
        final localFile = File('${dir.path}/$filename');
        final createdFile = await api.files.create(gFile,
            uploadMedia: ga.Media(localFile.openRead(), localFile.lengthSync()));
        print('New file created ${createdFile.id}');
        setState(() {});
      }
    ...
    

    For login:

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

    ...

    ...
    Future<void> login() async {
        try {
          account = await _googleSignIn.signIn();
          final client =
              GoogleHttpClient(await _googleSignIn.currentUser.authHeaders);
          api = ga.DriveApi(client);
        } catch (error) {
          print('DriveScreen.login.ERROR... $error');
          _scaffold.currentState.showSnackBar(SnackBar(
            backgroundColor: Colors.red.shade700,
            content: Text(
              'Error : $error',
              style: TextStyle(color: Colors.white),
            ),
          ));
        }
        setState(() {});
      }
    ...
    

    I think the possible cause of this problem is, It can not find the auth client in the background to upload files. What's your thought? and if I am right what will be the solution?