I tried some file search queries to communicate with Google Drive. If you don’t know how to connect to Google Drive, check this post first.
Template code and my file list
All examples use the following code. We change only the query.
Widget _createButton(String title, Function(drive.DriveApi driveApi) query) {
return ElevatedButton(
onPressed: () async {
final driveApi = await _getDriveApi();
if (driveApi == null) {
return;
}
final fileList = await query(driveApi);
final files = fileList.files;
if (files == null) {
return showMessage(context, "Data not found", "");
}
await _showList(files);
},
child: Text(title),
);
}
There are only 3 folders in my Google Drive. temp1 and temp2 folders have almost the same files.
If you need to create a hidden directory, which is only for the app, this post might be helpful.
Get All Files and Folders in the Drive
If we want to get all files, it’s very simple. We don’t have to specify any query for that.
Future<drive.FileList> _allFileList(drive.DriveApi driveApi) {
return driveApi.files.list(
spaces: 'drive',
);
}
Check if the file is a folder
It shows an icon depending on the file type in the example above. To show the proper icon, we need to check the mimeType. Since the folder type is always "application/vnd.google-apps.folder"
, we can check if it is a folder by using it.
const _folderType = "application/vnd.google-apps.folder";
Future<void> _showList(List<drive.File> files) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("List"),
content: Container(
width: MediaQuery.of(context).size.height - 50,
height: MediaQuery.of(context).size.height,
child: ListView.builder(
itemCount: files.length,
itemBuilder: (context, index) {
final isFolder = files[index].mimeType == _folderType;
return ListTile(
leading: Icon(isFolder
? Icons.folder
: Icons.insert_drive_file_outlined),
title: Text(files[index].name ?? "no-name"),
);
},
),
),
);
},
);
}
Get files in the root folder
This is the code to get files under the root folder. Normally, we need to specify an ID of the folder but we can use "root"
as the alias.
Future<drive.FileList> _root(drive.DriveApi driveApi) {
return driveApi.files.list(
spaces: 'drive',
q: "'root' in parents",
);
}
Get files in the specific folder
As I mentioned above, we need to specify a folder ID to get a file list in the folder. I couldn’t find a way to get the list with only one query.
Future<drive.FileList> _filesInFolder(drive.DriveApi driveApi) async {
final folderId = await _getFolderId(driveApi, "temp1");
return driveApi.files.list(
spaces: 'drive',
q: "'$folderId' in parents",
);
}
Future<String?> _getFolderId(
drive.DriveApi driveApi,
String folderName,
) async {
try {
final found = await driveApi.files.list(
q: "mimeType = '$_folderType' and name = '$folderName'",
$fields: "files(id, name)",
);
final files = found.files;
if (files == null) {
return null;
}
if (files.isNotEmpty) {
return files.first.id;
}
} catch (e) {
print(e);
}
return null;
}
The code gets a file list in temp1 folder.
Get files that contains specific words
It seems not to be possible to use wildcards for the query. Therefore, we can write only simple conditions by using "contains"
keyword.
Future<drive.FileList> _txt(drive.DriveApi driveApi) {
return driveApi.files.list(
spaces: 'drive',
q: "name contains '.txt'",
);
}
This query gets “.txt” files but if a file name is like “abc.txt.md”, it is also included in the result.
Get files that are owned by other users
Future<drive.FileList> _filesOwnedByOther(drive.DriveApi driveApi) async {
return driveApi.files.list(
spaces: 'drive',
q: "not 'me' in owners",
);
}
Get shared files
I couldn’t find a way to do this in a query. To get files that are shared with others, we need to check the "shared"
property. It can be done only after we get the file list.
Future<drive.FileList> _sharedFiles(drive.DriveApi driveApi) async {
final list = await driveApi.files.list(
spaces: 'drive',
q: "'me' in owners",
);
// remove non-shared files
list.files?.removeWhere((element) => element.shared == false);
return list;
}
It includes both folder and file. temp1 folder is shared with another user.
Comments
Is I can use the driveReadonlyScope without verification? When I add this scope and run app I select my google account and a pop-up appears that google has not verified this app when I select continue the another pop-up show that something went wrong why?