How to retrieve multiple different files form firebase to flutter - flutter

I don't want to upload my code but I am having problems with retrieving multiple files from firebase storage. So in my app, I want to make users upload different files and while uploading it will show up in a list form.
The thing is I am able to save files into the firebase storage but I am freaking out trying to retrieve them into my application. I really hope if I get some to help me with this.

I don't exactly know what you're trying to achieve but maybe this would help.
When you upload your file to firestore storage, get a download link of that file and store it in the collection. Then you can retrieve the list of files you have uploaded.
Get the download URL of the uploaded file
UploadTask imageUploadTask = storageReference.putFile(file);
await imageUploadTask.whenComplete(() async {
mediaURL = await imageUploadTask.snapshot.ref.getDownloadURL();
print("download url = $mediaURL");
return mediaURL;
}).catchError((err){
print(err.toString());
});
Save URL to the collection
final CollectionReference _filesCollectionReference = FirebaseFirestore.instance.collection("files");
Map<String, String> file = {
"downloadURL" : url,
};
var result = await _filesCollectionReference.add(file);
Retrieve files
await _filesCollectionReference.get();

Related

Google Drive in Flutter | Update API not working

I'm developing a flutter app where I upload files to google drive which works like magic. I get the ID using response.id derived from DriveApi.files.create which looks something like this :
var createResponse = await drive.files.create(
fileToUpload,
uploadMedia: googledrive.Media(file.openRead(), file.lengthSync()),
)
Now, Let's say I want to update this file. In that case, I'm using the drive's update API. My call looks something like this :
var updateResponse = await drive.files.update(fileToUpload, fileId,
uploadMedia: googledrive.Media(file.openRead(), file.lengthSync()));
This fileId is the ID I get from create response (File's ID that gets returned after the create file)
The issue, however is, that I do NOT get any response in the updateResponse. I checked drive and nothing is getting updated. Any idea what I'm doing wrong? Any input would be really appreciated.

Sharing a text file (csv) with share_plus: "unable to attach file"

I want to get data from Firestore, convert it into csv format, then share it using the user's method of choice (e.g. email). I'm using the csv package to convert the data to csv, the path_provider to get the directory to write the file to the phone, and the share_plus package to share the file.
However, when I tap a share method (e.g. Gmail, Outlook, Whatsapp), it opens the right app but then I get a message on the phone like "Unable to attach file" (but there is no error in my app). The file is definitely being written as I can read it and it comes back with the expected string. The ShareResultStatus that is returned by the share is 'successful' Can anyone figure it out what the problem is and how to fix it?
Here is my code:
Future exportData() async {
// Dummy data (in reality, this will come from Firestore)
List<List> dummyData = [
['Date', 'Piece', 'Rating'],
[DateTime.utc(2022, 05, 01), 'Sonata', 4],
[DateTime.utc(2022, 05, 02), 'Sonata', 2],
];
// Turn into CSV
String csvData = _convertToCsv(dummyData);
// Write to local disk
await _writeData(csvData);
// Share
String filePath = await _filePath;
final result =
await Share.shareFilesWithResult([filePath], mimeTypes: ['text/csv']);
print(result.status);
}
And here are the functions used in above code:
Future<String> get _filePath async {
final directory = await getApplicationDocumentsDirectory();
return '${directory.path}/my_practice_diary_data.csv';
}
Future<File> _writeData(String csvData) async {
String filePath = await _filePath;
final file = File(filePath);
return file.writeAsString(csvData);
}
String _convertToCsv(List<List> data) {
String result = const ListToCsvConverter().convert(data);
return result;
}
Note: I've tried doing it both as txt and csv files, got same result
*** EDIT (06/06/2022): After a lot of reading and watching youtube videos, I have come to realise that the problem is that the directory getApplicationDocumentsDirectory() is only accessible by my app (and hence the app that is is being shared to, like gmail, cannot read it).
For now I have worked around it by using the package mailer and using user's google credentials to send emails (I followed these helpful youtube tutorials: Flutter Tutorial - How To Send Email In Background [2021] Without Backend and Flutter Tutorial - Google SignIn [2021] With Firebase Auth - Android, iOS, Flutter Web.
However, it would still be nice to know a nice way to generate a file and share it using share_plus, as per my original question. I believe that this can be achieved via one of two ways:
Find a way to allow other apps to access this specific file in the app directory; or
Find a way to download the file into an external storage (like downloads folder), then share that. (I cannot find a way to do this on both Android and iOS).
Anyone who knows how to do these or any other solution to the problem, please share!

How to download a pdf file using Flutter?

void getHttp() async
{
print("Got called");
var response = await Dio().download('https://www.google.com/', 'assets/xx.html');
print("DDDDD:");
print(response);
}
The directory assets is present with read and write permissions.
I am calling this on the press of a button. "Got called" DOES get printed.
There are no errors present, still "DDDDD" doesn't get printed.
The xx.html doesn't get saved.
Where am I going wrong?
Based on documentation the syntax for Dio to download a file is
var response = await Dio().download('https://www.google.com/', <<Destination directory from which your app is running. Like internal storage or external storage.>>);
I guess you are providing the file path which is associated with the projects assets directory where the file cannot be downloaded since it is bundled with the app.
Use the following package to access the device file system and provide that path to download your file.
var response = await Dio().download('https://www.google.com/', <<Path from internal storage.>>);

In Flutter, how can I access a Google Docs document by it document ID?

Background
In Google Apps Script I can access an existing document in Google Drive by calling DocumentApp and using the openById method. For example:
var documentToAccess = DocumentApp.openById(documentId);
Similarly, I can access a file in Google Drive bu calling DriveApp.getFileById. For example:
var fileToAccess = DriveApp.getFileById(documentId);
Problem
In Flutter, the googleapis dependency allows me to import several libraries including googleapis/drive/v3.dart, googleapis/docs/v1.dart, and googleapis/file/v1.dart which provide methods to access the attributes of files in Google Drive, but I can’t seem to find a method to actually get or open the file that I want to work on.
Question
In Flutter, how can I get a Google Docs document by its document ID so that I can then work on that document?
googleapis Documentation and Other Attempts
The googleapis documentation has some useful resources but despite attempting to implement these I can’t seem to get what I need. For example:
var fileToAccess = DriveApi().files.get('documentId’);
var fileToAccess = Document().documentId;
var fileToAccess = FilesResourceApi().get('documentId');
It looks like the user is not signed in, so first, sign in the user.
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: <String>[
'email',
'https://www.googleapis.com/auth/documents.readonly',
'https://www.googleapis.com/auth/drive.readonly'
],
);
To instantiate the client you would add something like:
final client = MyClient(defaultHeaders: {
'Authorization': 'Bearer ${authentication.accessToken}'
});
and then where you try to get the document :
DriveApi driveApi = DriveApi(client);
var files = await driveApi.files
.list(q: 'mimeType=\'application/vnd.google-apps.document\'');

Saving Cache from api response on flutter

I Would like to seek advice for a simple way to cache this response from my API on flutter. What I am intending to do is when there no internet available it will use the cache item and if there is internet available it will update the cache to the latest one.The code below is the current API call that I am using.
_getCurrentPlanDetails() async{
var url = "http://dmp-portal-fixture.herokuapp.com/getCurrentPlan";
var response = await http.get(url);
if (response.statusCode == 200){
var jsonResponse = convert.jsonDecode(response.body);
setState(() {
currentPlan = jsonResponse["data"]["CurrentPlan"];
cutOffDate = jsonResponse["data"]["CutoffDate"];
contractExpiry = jsonResponse["data"]["ContractExpiry"];
monthsRemaining =jsonResponse["data"]["MonthsRemaining"];
});
print("get Current plan");
}else{
print("error current plan");
}
}
There are multiple packages that handle this depending on the use-case of your requirements:
localstorage which is a JSON based storage.
shared_preferences for storing key-value pairs.
flutter_secure_storage for storing all your access token and security related components of the app such as all session information, user credentials etc...
SQL database there is a quite extensive tutorial on storing files in a databese in Flutter, so I suggest reading that one as well in case you need to preserve a lot of app related data in case no internet is available.