Firebase Storage image does not upload properly - firebase

am trying to send an image that I take from phone to Firebase storage. the first function gets the image with the image picker plugin and passing the path return in as argument for the upload function.the image uploads to cloud storage but however in the panel the type is application/octet-stream and the image does not show
String download_path;
var imageFile;
picker() async{
File theImage = await ImagePicker.pickImage(
source: ImageSource.gallery);
imageFile = theImage;
var theimagepath = theImage.path;
setState(() {
imageFile = theImage;
});
}
Future<Null> uploadFile(String myfilepath)async{
final RegExp regExp = RegExp('([^?/]*\.(jpg))');
final filename = regExp.stringMatch(myfilepath);
final Directory tempDir = Directory.systemTemp;
final File thefile = await File('${tempDir.path}/$filename').create();
final StorageReference sref = FirebaseStorage.instance.ref().child('storeFolderName').child(filename);
final StorageUploadTask uploadTask = sref.putFile(thefile);
final Uri downloadUrl = (await uploadTask.future).downloadUrl;
download_path = downloadUrl.toString();
print('download url printed : $download_path');
}
IconButton(
icon: Icon(Icons.cloud_done),
onPressed: (){uploadFile(imageFile.toString());
},
),
log output:
D/Surface (18601): Surface::setBufferCount(this=0x9272d800,bufferCount=4)
D/GraphicBuffer(18601): register, handle(0x97ee29c0) (w:480 h:854 s:480 f:0x1 u:f02)
D/GraphicBuffer(18601): register, handle(0x97ee2e40) (w:480 h:854 s:480 f:0x1 u:f02)
D/GraphicBuffer(18601): register, handle(0x8ea20140) (w:480 h:854 s:480 f:0x1 u:f02)
W/System (18601): ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
I/System.out(18601): e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaHttp
I/System.out(18601): [OkHttp] sendRequest<<
D/GraphicBuffer(18601): register, handle(0x8ea21040) (w:480 h:854 s:480 f:0x1 u:f02)
W/System (18601): ClassLoader referenced unknown path: system/framework/mediatek-cta.jar
I/System.out(18601): e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaHttp
I/System.out(18601): [OkHttp] sendRequest<<
I/flutter (18601): download url printed : https://firebasestorage.googleapis.com/v0/b/cloud-fs-demo.appspot.com/o/storeFolderName%2FIMG_20180711_080138.jpg?alt=media&token=6fb05871-04df-458d-93bc-1951cd122770
E/[EGL-ERROR](18601): __egl_platform_cancel_buffers:644: surface->num_buffers(4)

It doesn't really make sense to me that if you have the file why send the path to the file? What seems to be the error is that it doesn't find the location of the file. Instead, I would do something like this:
String download_path;
var imageFile;
picker() async{
File theImage = await ImagePicker.pickImage(
source: ImageSource.gallery);
imageFile = theImage;
var theimagepath = theImage.path;
setState(() {
imageFile = theImage;
});
}
Future<Null> uploadFile(File myFile)async{
final StorageReference sref =
FirebaseStorage.instance.ref().child('storeFolderName').child(myFile.toString());
final StorageUploadTask uploadTask = sref.putFile(myFile);
final Uri downloadUrl = (await uploadTask.future).downloadUrl;
download_path = downloadUrl.toString();
print('download url printed : $download_path');
}
IconButton(
icon: Icon(Icons.cloud_done),
onPressed: (){uploadFile(imageFile);
},
),

I have the same issue. The auto detect mime type doesn't seems to work, so I end up using the mime package and sending the mime type in StorageMetadata.

I also face this issue and after two days finally solve this by adding metaData, contentType. What interesting that in my case the same code work for android but was wrong for iOS.
so here is a code snippet which I use:
final File selectedImage = await ImagePicker.pickImage(
source: ImageSource.gallery,
);
filePath = selectedImage.path;
currentFile = selectedImage;
final StorageReference storageRef =
FirebaseStorage.instance.ref().child('images');
final StorageUploadTask task = storageRef.child('myImage.jpeg').putFile(selectedImage, StorageMetadata(contentType: 'image/jpeg'));
await task.onComplete; // do something
So without StorageMetadata of putFile method the images is uploading as application/octet-stream (only on iOS). But with metaData work just fine for me. Hope that was helpful.

Related

Define Firebase cloud storage path in flutter

I am having trouble defining path for Firebase cloud storage.
I would like it to be -
user id -> firestore doc id -> folder's name.
currently, I successfully save the images in this way.
class FirebaseStorageService {
final String imageName;
FirebaseStorageService({required this.imageName});
get imageFileName =>
imageName + DateTime.now().millisecondsSinceEpoch.toString();
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
//get user id
final String? userid = FirebaseAuth.instance.currentUser!.uid;
//! Upload gallery
Future<String> saveGalleryInCloudStorage({
required File file,
}) async =>
await upload(
file: file,
path: '$userid/$postid/Property Gallery/$imageFileName',
contentType: 'image/png');
/// Generic file upload for any [path] and [contentType]
Future<String> upload({
required File file,
required String path,
required String contentType,
}) async {
final storageReference = FirebaseStorage.instance.ref().child(path);
final uploadTask = storageReference.putFile(
file, SettableMetadata(contentType: contentType));
final snapshot = await uploadTask;
final downloadUrl = await snapshot.ref.getDownloadURL();
return downloadUrl;
}
}
However, the problem I am having is the postid (that is used in firebase cloud storage path) is not same with firestore doc id.
How do I make them to be the same?
Thanks in advance!!
.collection('properties').doc()
the doc is empty hence firebase generates an auto id.
What you can do is Create an empty doc get a doc id, use the id to save the file, and when saving your firestore doc just update the empty doc
create empty doc
final documentReference = await FirebaseFirestore.instance.collection('mycoll').add({'id':''});
use doc id to save file obtained from
documentReference.id
makes this redudant
//get firestore doc id
final postid = FirebaseFirestore.instance.collection('properties').doc().id;
on done saving file , save your doc with the id above
FirebaseFirestore.instance.collection('properties').doc(documentReference.id)
.set(servicemodel.toJson());```
You can upload Image and update fields related withthis function. Its work for me.
static String staticImagePath= "";
final FirebaseAuth _auth = FirebaseAuth.instance;
File? file;
Future uploadImageToFirebaseStorage() async {
var _user = _auth.currentUser!.uid;
var _propertiesCollection= FirebaseFirestore.instance
.collection('Properties')
.where('postId', isEqualTo: _user);
var querySnapshots = await _propertiesCollection.get();
try {
var _image = await ImagePicker().pickImage(source: ImageSource.gallery);
file = File(_image!.path);
firebase_storage.Reference _refPath = firebase_storage
.FirebaseStorage.instance
.ref()
.child('MyImageRepo')
.child(_auth.currentUser!.uid);
firebase_storage.UploadTask _uploadTask = _refPath.putFile(file!);
String _url = await (await _uploadTask).ref.getDownloadURL();
staticImagePath = _url.toString();
await _propertiesCollection.doc(_auth.currentUser!.uid).update(({
'postId': staticImagePath,
}));
} catch (e) {
return Center(child: Text(e.toString()));
}
}

How I can view my uploaded pdf from firebase storage with flutter?

I have recently uploaded a pdf file to firebase storage via picking a pdf by file_picker plugin.
now file is uploaded successfully :
but when I go to firebase storage : tapped on that pdf link , showing ERROR MESSAGE failed to load pdf decoument
Code for picking pdf via file_picker
void sendPdf() async {
FilePickerResult result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['pdf'],
);
if(result != null) {
File file = File(result.files.single.path);
_storageMethods.uploadPdf(
pdf: file,
uploaderId: widget.adminUser.uid,
courseTitle:_courseTitleController.text,
coursePrice:_coursePriceController.text,
uploadProvider: _uploadProvider);
} else {
// User canceled the picker
}
}
Code for uploading a file to firebase storage:
Future<String> uploadPdfToStorage(File pdfFile) async {
try {
Reference ref = FirebaseStorage.instance.ref().child('pdfs/${DateTime.now().millisecondsSinceEpoch}');
UploadTask uploadTask = ref.putFile(pdfFile, SettableMetadata(contentType: 'pdf'));
TaskSnapshot snapshot = await uploadTask;
String url = await snapshot.ref.getDownloadURL();
print("url:$url");
return url;
} catch (e) {
return null;
}
}
Have found the issue with contentType
UploadTask uploadTask = ref.putFile(pdfFile, SettableMetadata(contentType: 'pdf'));
I've replaced with:
UploadTask uploadTask = ref.putFile(pdfFile, SettableMetadata(contentType: 'application/pdf'));

Unable to upload file to Firebase Storage using Flutter Web's image_picker

I'm using flutter web. I'm trying to upload an image using image_picker and store in firebase storage. The image_picker returns PickedFile type. So, I'm converting it to File type using File image = File(pickedFile.path) and then upload using ref.putFile(image). But the file doesn't get uploaded. I'm getting a Namespace exception. Any ideas?
PickedFile pickedFile =
await picker.getImage(source: ImageSource.gallery);
File newFile = File(pickedFile.path);
var now = DateTime.now().millisecondsSinceEpoch;
StorageReference reference =
FirebaseStorage.instance.ref().child("images/$now");
StorageUploadTask uploadTask = reference.putFile(newFile);
//Upload the file to firebase
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
// Waits till the file is uploaded then stores the download url
String url = await taskSnapshot.ref.getDownloadURL();
The error I'm getting is
Error: Unsupported operation: _Namespace
at Object.throw_ [as throw] (http://localhost:64148/dart_sdk.js:4322:11)
at Function.get _namespace [as _namespace] (http://localhost:64148/dart_sdk.js:54027:17)
at io._File.new.existsSync (http://localhost:64148/dart_sdk.js:51618:51)
at firebase_storage.StorageReference.__.putFile (http://localhost:64148/packages/firebase_storage/firebase_storage.dart.lib.js:701:27)
at add_product$46view._AddProductPageState.new.loadAssets (http://localhost:64148/packages/ecommerce_glasses/product/views/add_product.view.dart.lib.js:1234:38)
at loadAssets.next (<anonymous>)
at http://localhost:64148/dart_sdk.js:37211:33
at _RootZone.runUnary (http://localhost:64148/dart_sdk.js:37065:58)
at _FutureListener.thenAwait.handleValue (http://localhost:64148/dart_sdk.js:32049:29)
at handleValueCallback (http://localhost:64148/dart_sdk.js:32596:49)
at Function._propagateToListeners (http://localhost:64148/dart_sdk.js:32634:17)
at _Future.new.[_completeWithValue] (http://localhost:64148/dart_sdk.js:32477:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:64148/dart_sdk.js:32499:35)
at Object._microtaskLoop (http://localhost:64148/dart_sdk.js:37326:13)
at _startMicrotaskLoop (http://localhost:64148/dart_sdk.js:37332:13)
at http://localhost:64148/dart_sdk.js:32851:9
You don't have access to the file path in Flutter web.
Instead of trying to upload the file from a path you need to upload the file as bytes.
You can get the file as Uint8List using this,
final fileBytes = pickedFile.readAsBytes();
And in your storage code, you can put the data instead,
reference.putData(fileBytes);
So, your code should look something like this
PickedFile pickedFile =
await picker.getImage(source: ImageSource.gallery);
final fileBytes = pickedFile.readAsBytes();
var now = DateTime.now().millisecondsSinceEpoch;
StorageReference reference =
FirebaseStorage.instance.ref().child("images/$now");
StorageUploadTask uploadTask = reference.putData(fileBytes);
//Upload the file to firebase
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
// Waits till the file is uploaded then stores the download url
String url = await taskSnapshot.ref.getDownloadURL();
Add this scripts in index.html
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-storage.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.4/firebase-firestore.js"></script>
this is how im doing it
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase/firebase.dart' as fb;
Future<Uri> _uploadImageFile({
#required html.File image,
#required String imageName,
}) async {
fb.StorageReference storageRef = fb.storage().ref('category/$imageName');
fb.UploadTaskSnapshot uploadTaskSnapshot =
await storageRef.put(image).future;
Uri imageUri = await uploadTaskSnapshot.ref.getDownloadURL();
return imageUri;
}
You cannot use File newFile = File(pickedFile.path); in Flutter web. I don't know how the Firebase API works, but you will probably have to make use of pickedFile.readAsBytes().

How to upload image to web (firestore) - Flutter web

so i've tried to upload an image to firestore, but it gives me the error Unsupported operation: _Namespace.
Here's my method:
File pickedImage;
Future<Uri> uploadPic() async {
FirebaseStorage _storage = FirebaseStorage.instance;
StorageReference reference = _storage.ref().child("profile_pictures/");
StorageUploadTask uploadTask = reference.putFile(pickedImage);
Uri dowurl = await (await uploadTask.onComplete).ref.getDownloadURL();
return dowurl;
}
Try adding a name to the file you want to save:
StorageReference reference = _storage.ref().child("profile_pictures/ –add Name here –");
You might also remove the / that comes after profile_pictures, if you don‘t want to add another reference

How to get the download URL from firebase with flutter?

I would like to retrieve the Download URL of a private image in firbase storage.
Hi have tried many of the suggestions on the site, but all of them end up in the same result.
I have tried the following code:
getImageNow() async {
StorageReference ref =
FirebaseStorage.instance.ref().child("/1.jpg");
String url = (await ref.getDownloadURL()).toString();
return url;
}
It works when i print the url inside the function, but when i try to call print(getImageNow())to get the url, i just get "Instance of 'Future<dynamic>'"
UPDATE*************
In the end i am trying to get somthing like this:
return Image.network(
getImageNow(),
);
But i can not get it to work with async.
Since getImageNow() is asynchronous (as indicated by the async keyword), you will need to use await to make the calling code wait for the result:
print(await getImageNow())
What await does here is that it essentially unwraps the Future and is equivalent to:
getImageNow().then((value) => print(value));
this is how i upload and get the download url
this part is how i get image from picker
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
print('Image Path $_image');
});
}
then i upload it
Future uploadPic(BuildContext context) async {
String fileName = basename(_image.path);
StorageReference firebaseStorageRef = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
final String url = (await taskSnapshot.ref.getDownloadURL());
print('URL Is $url');
}
hope it will help someone

Resources