how can i send Thumbnail from a video to firebase storage - firebase

i am developing flutter app and i need to send Thumbnail from a video to firebase storage
i am trying to do somthing like this
Uint8List VideoThumbnail ;
onPressed: () async {
final result = await FilePicker.platform.pickFiles(allowMultiple: false, );
final path = result.files.single.path;
setState(() => file = File(path));
if (file == null) {
return;
}
final img = await VideoCompress.getByteThumbnail(file.path) ;
// setState(() => this.VideoThumbnail = img );
if (file == null) return;
final fileName = basename(file.path);
final destination = 'files/$fileName';
task = FirebaseApi.uploadFile( destination,file); // here wont accept VideoThumbnail variable
setState(() {});

Related

The argument type 'Object?' can't be assigned to the parameter type 'Map<String, dynamic>' Using DataSnapshot to get data from my models

I am getting error with the _getUserDetails() async METHOD ON LINE
userProfile = UserProfileBrowse.fromMap(Map<String, dynamic>.from(snapshot.value));
This is my Data model
My Data model class where I am using Map
Picture of my error
Error is in the title
Error line
HERE IS THE VIDEO I AM FOLLOWING
Youtube video of the coing
HERE IS THE CODE OF MY PAGE
class _ProfileScreenState extends State<ProfileScreen> {
User? user;
UserProfileBrowse? userProfile;
DatabaseReference? userRef;
File? imageFile;
bool showLocalFile = false;
_getUserDetails() async {
DataSnapshot snapshot = (await userRef!.once()) as DataSnapshot;
//ERROR IS HERE
userProfile = UserProfileBrowse.fromMap(Map<String, dynamic>.from(snapshot.value));
setState(() {});
}
_pickImageFromGallery() async {
XFile? xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
if( xFile == null ) return;
final tempImage = File(xFile.path);
imageFile = tempImage;
showLocalFile = true;
setState(() {
});
// upload to firebase storage
try{
var fileName = userProfile!.email + '.jpg';
UploadTask uploadTask = FirebaseStorage.instance.ref().child('profile_images').child(fileName).putFile(imageFile!);
TaskSnapshot snapshot = await uploadTask;
String profileImageUrl = await snapshot.ref.getDownloadURL();
print(profileImageUrl);
} catch( e ){
print(e.toString());
}
}
_pickImageFromCamera() async {
XFile? xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
if( xFile == null ) return;
final tempImage = File(xFile.path);
imageFile = tempImage;
showLocalFile = true;
setState(() {
});
}
#override
void initState() {
super.initState();
user = FirebaseAuth.instance.currentUser;
if (user != null) {
userRef =
FirebaseDatabase.instance.ref().child('userProfileBrowse').child(user!.uid);
}
_getUserDetails();
}
You should refrain from using screenshots of relevant portions of your code in question. Your data model code should just be embedded into your post just like your other code.
Assuming your data returns in the form of a Map, you should be able to omit the .from function and just cast snapshot.value to a Map and pass it directly to your fromMap function.
userProfile =
UserProfileBrowse.fromMap(snapshot.value as Map<String, dynamic>);
That will definitely get rid of the compiler error but depending on how your data is structured you may get a run time error.

Saving to Firebase storage not possible in an isolate

I have an app feature where the user picks images from his phone and then uploads them to Firebase Storage.
I thought that the upload process should be done in a separate isolate.
I keep getting an exception which I think is related to the Multi Image Picker package.
The exception is:
E/flutter (12961): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)]
Unhandled Exception: Exception: NoSuchMethodError: The getter
'defaultBinaryMessenger' was called on null.
When the user presses on the upload button, this method is called:
Future<void> _initIsolate() async {
ReceivePort receivePort = ReceivePort();
receivePort.listen(
(message) {
print(message.toString());
},
onDone: () => print('Done'),
onError: (error) => print('$error'),
);
await compute(
_function, // This function is called in the separate isolate
{
'sendingPort': receivePort.sendPort,
'images': images,
},
);
}
The _function method is as follows:
static void _function(Map<String, dynamic> parameterMap) async {
SendPort sendingPort = parameterMap['sendingPort'];
List<Asset> images = parameterMap['images'];
List<String> urls = [];
int index = 0;
images.forEach(
(image) async {
String url = await getDownloadUrl(image); // a helper method
urls.add(url);
sendingPort.send('Image number: $index uploaded');
index += 1;
},
);
final CollectionReference collectionRef = FirebaseFirestore.instance.collection('offers');
final user = CurrentUser.getCurrentUser();
await collectionRef.doc(user.uid).set(
{
'time': FieldValue.serverTimestamp(),
'urls': urls,
},
);
}
The helper method _getDownloadUrl is as follows:
Future<String> getDownloadUrl(Asset image) async {
String rannum = Uuid().v1();
final ByteData byteData = await image.getByteData(); // --> This produces a defaultBinaryMessenger
final List<int> imageData = byteData.buffer.asUint8List();
Reference reference = FirebaseStorage.instance.ref().child("offers/$rannum");
UploadTask uploadTask = reference.putData(imageData);
TaskSnapshot downloadUrl = await uploadTask.whenComplete(() => null);
Future<String> futureUrl = downloadUrl.ref.getDownloadURL();
return futureUrl;
}
The getByteData method is part of the multi_image_picker package.
The source code is:
Future<ByteData> getByteData({int quality = 100}) async {
if (quality < 0 || quality > 100) {
throw new ArgumentError.value(
quality, 'quality should be in range 0-100');
}
Completer completer = new Completer<ByteData>();
ServicesBinding.instance.defaultBinaryMessenger // --> Exception here. ServicesBinding.instance is null
.setMessageHandler(_originalChannel, (ByteData message) async {
completer.complete(message);
ServicesBinding.instance.defaultBinaryMessenger
.setMessageHandler(_originalChannel, null);
return message;
});
await MultiImagePicker.requestOriginal(_identifier, quality);
return completer.future;
}
Why is the ServicesBinding.instance null?
Since this method is working fine without using Isolates, does this have something to do with the isolates?

How to download the PDF file after uploading to the Firebase storage, and show in the Flutter application and keep it always static

How to download the pdf after uploading to the firebase storage, and show in the flutter application and keep it always static.
I mean when ever user visits that flutter page or screen in the application, the pdf file downloaded should be opened on a click eventon a icon or image etc. It should not disappear after closing the application, when we open the application for the second time.
User should be able to download and view or open the PDF whenever he wish.
This is my code I have tried as below:
uploadToFirebase() {
if (_multiPick) {
_paths.forEach((fileName, filePath) => {upload(fileName, filePath)});
} else {
String fileName = _path.split('/').last;
String filePath = _path;
upload(fileName, filePath);
}
}
upload(fileName, filePath) {
_extension = fileName.toString().split('.').last;
StorageReference storageRef =
FirebaseStorage.instance.ref().child(fileName);
final StorageUploadTask uploadTask = storageRef.putFile(
File(filePath),
StorageMetadata(
contentType: '$_pickType/$_extension',
),
);
setState(() {
_tasks.add(uploadTask);
});
}
Future<void> downloadFile(StorageReference ref) async {
final String url = await ref.getDownloadURL();
final http.Response downloadData = await http.get(url);
final Directory systemTempDir = Directory.systemTemp;
final File tempFile = File('${systemTempDir.path}/tmp.jpg');
if (tempFile.existsSync()) {
await tempFile.delete();
}
await tempFile.create();
final StorageFileDownloadTask task = ref.writeToFile(tempFile);
final int byteCount = (await task.future).totalByteCount;
var bodyBytes = downloadData.bodyBytes;
final String name = await ref.getName();
final String path = await ref.getPath();
print(
'Success!\nDownloaded $name \nUrl: $url'
'\npath: $path \nBytes Count :: $byteCount',
);
_scaffoldKey.currentState.showSnackBar(
SnackBar(
backgroundColor: Colors.white,
content: Image.memory(
bodyBytes,
fit: BoxFit.fill,
),
),
);
}
This code only uploads pdf file but do not download and show pdf where as it is uploading image and downloading, showing image files
Yes Finally I have successfully downloaded the pdf file after uploading it to firebase storage in this way
`void filePicker(BuildContext context) async {
try {
PDfFile1 = await FilePicker.getFile(type: FileType.custom, allowedExtensions: ['pdf']);
fileName = p.basename(PDfFile1.path);
setState(() {
fileName = p.basename(PDfFile1.path);
isPDF_selected=true;
});
print(fileName);
// _uploadFile(PDfFile1, fileName);
} on PlatformException catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Sorry...'),
content: Text('Unsupported exception: $e'),
actions: <Widget>[
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
}
);
}
}
Future<void> _uploadFile(File PDFFile1, String filename) async {
if (FileType == 'pdf') {
PDfFile1 = await FilePicker.getFile(type: FileType.custom, allowedExtensions: ['pdf']);
fileName = p.basename(PDfFile1.path);
setState(() {
fileName = p.basename(PDfFile1.path);
isPDF_selected=true;
});
print(fileName);
// _uploadFile(PDfFile1, fileName);
}
final FirebaseStorage _storage4 =
FirebaseStorage(storageBucket: 'gs://flutter-cb66a.appspot.com');
//StorageUploadTask uploadTask4;
String PDFPath = 'DeviceDocs/DeviceDocs${DateTime.now()}.pdf';
final StorageReference _storagepdfreference = FirebaseStorage().ref().child(PDFPath);
StorageUploadTask uploadTask4 = _storagepdfreference.putFile(PDfFile1);
StorageTaskSnapshot downloadPDFUrl = (await uploadTask4.onComplete);
String url = (await downloadPDFUrl.ref.getDownloadURL());
print("URL is $url");
setState(() {
uploadTask4 = _storage4.ref().child('DeviceDocs/DeviceDocs${DateTime.now()}.pdf').putFile(PDfFile1);
_PDFUploaded= true;
});
}
Future downloadPDfFile1() async {
String downloadAddress= await _storagepdfreference.getDownloadURL();
setState(() {
_downloadPDFUrl= downloadAddress;
});
}
`
But Now I want to open the pdf directly from the pdfUrl. How to do so ?

How to encode a PDF to a binary in Flutter

I am trying to make an document scanner app in flutter where whenever a user clicks a button the PDF that is already created should be added to an SQLite database .For uploading a PDF into a SQLite database in flutter we need to convert the file to a binary.But I don't know how to do that please help me.The code for converting a image to a pdf
String _status = "Not created";
File pdfFile;
FileStat _pdfStat;
bool _generating = false;
Future<File> _assetFromBundle(String name) async {
final tempDir = await getApplicationDocumentsDirectory();
final output = File(path.join(tempDir.path, name));
if (!await output.exists()) {
final data = await rootBundle.load('assets/$name');
final buffer = data.buffer;
output.writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
return output;
}
Future<void> _createPdf() async {
try {
this.setState(() => _generating = true);
final tempDir = await getApplicationDocumentsDirectory();
final output = File(path.join(tempDir.path, 'example.pdf'));
this.setState(() => _status = 'Preparing images...');
final images = [ff.image];
this.setState(() => _status = 'Generating PDF');
await ImagesToPdf.createPdf(
pages: images
.map(
(file) => PdfPage(
imageFile: file,
compressionQuality: 0.5,
) ,
)
.toList(),
output: output,
);
_pdfStat = await output.stat();
this.setState(() {
pdfFile = output;
_status = 'PDF Generated (${_pdfStat.size ~/ 1024}kb)';
});
} catch (e) {
this.setState(() => _status = 'Failed to generate pdf: $e".');
} finally {
this.setState(() => _generating = false);
}
}
Future<void> _openPdf() async {
if (pdfFile != null) {
try {
final bytes = await pdfFile.readAsBytes();
await Printing.sharePdf(
bytes: bytes, filename: path.basename(pdfFile.path));
} catch (e) {
_status = 'Failed to open pdf: $e".';
}
}
}
I guess what you are looking for is bytes, use File class to read as bytes,
var f = File('file/path.pdf');
List<int> binaries = await f.readAsBytes();
use the bytes as is or by encoding it to Base64 String
var asString = Base64Codec().encode(binaries);

Flutter: 'file.existsSync()' seems to be always false on IOS-Devices when trying to upload a video to firebase_storage

I'm trying to upload videos from the users gallery to firebase_storage.
Firstly, the user picks the video:
final File file = await ImagePicker.pickVideo(
source: ImageSource.gallery,
);
// Video compression
MediaInfo info;
if (Platform.isIOS) {
info = await _flutterVideoCompress.getMediaInfo(file.path);
} else {
info = await _flutterVideoCompress.compressVideo(
file.path,
deleteOrigin: true,
quality: VideoQuality.MediumQuality,
includeAudio: true,
);
}
setState(() {
_galleryFile = info.file;
});
After the video-file is selected (and on android compressed, ios does it automatically) the user can trigger the upload:
try {
var timestamp = DateTime.now().millisecondsSinceEpoch.toString();
var type = user.type;
var typeString = type == 0 ? 'player' : type == 1 ? 'trainer' : 'club';
String fileName = '${id}_$timestamp';
StorageReference reference = FirebaseStorage.instance
.ref()
.child(typeString)
.child(
'$typeString-upload-${_fileType == 'video' ? 'video' : 'images'}')
.child(id)
.child(fileName);
setState(() {
isLoadingUpload = true;
});
_uploadTask = reference.putFile(_galleryFile, StorageMetadata(contentType: 'video/mp4'));
.
.
.
catch (e) {
print(e);
}
But the code already failes at uploadTask = reference.putFile(_galleryFile, StorageMetadata(contentType: 'video/mp4')); with 'file.existsSync() is not true'.
Tested on iPhone 7 and iPhone XR.
Everything works perfectly on android.
Thanks in advance.

Resources