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}");
}
Comments
-
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 withworkmanager
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?