Flutter Firebase Storage video gets rotated - firebase

I'm not sure this is flutter or Firebase Storage.
I captured video with my iPhone portrait mode and uploaded to Firebase Storage. When I play that video, it gets rotated. So it looks wired like video is stretched to the screen. I guess it looks ok if you see it in landscape mode but since I disable my app to rotate, there is no way to see it correct aspect ratio.
I upload video and play it like so.
Future _upload(File file) async {
try {
String now = DateTime.now().millisecondsSinceEpoch.toString();
String storageId = (now + uid);
String contentType = 'video/mp4';
StorageReference ref = FirebaseStorage.instance.ref().child("video").child(storageId);
StorageUploadTask uploadTask = ref.putFile(file, StorageMetadata(contentType: contentType));
Uri downloadUrl = (await uploadTask.future).downloadUrl;
String url = downloadUrl.toString();
print(url);
} catch (error) {
print(error);
}
}
VideoPlayerController _controller;
new AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: new VideoPlayer(_controller)
)
Does anyone know how to fix this?

This seems to be this known issue https://github.com/flutter/flutter/issues/17606
with a pending pull request https://github.com/flutter/flutter/issues/17606#issuecomment-415621941
Please upvote the issue to increase priority.

Related

How can i get Image URL from Firebase Storage to Firebase Database without uploading image from my app?

I upload one image from my computer to Firebase Storage and now I want that image to get in my Firebase database with his information and display it in my app. I can display information but cant display images. I google also but in every answer, they say first to upload the image to firebase storage from the app. then get his URL in the database and I don't want to upload from my app.
So if someone know then help.
You Can Get the download link for your image Like this
static final firebase_storage.FirebaseStorage storage =
firebase_storage.FirebaseStorage.instance;
String url = await storage
.ref('YourImagePath')
.getDownloadURL();
In addition to SARADAR21's excellent answer on how to get the data for a file at a known path, you can also list the files in Cloud Storage through the API, in case you don't know the path.
From that documentation:
final storageRef = FirebaseStorage.instance.ref();
final listResult = await storageRef.listAll();
for (var prefix in listResult.prefixes) {
// The prefixes under storageRef.
// You can call listAll() recursively on them.
}
for (var item in listResult.items) {
// The items under storageRef.
}
You can then use the references you get this way, and call getDownloadUrl() to get a download URL for each of them.
Future<QuerySnapshot?> getDataFromFirebase() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
FirebaseFirestore.instance
.collection('Images')
.get()
.then((QuerySnapshot? querySnapshot) {
querySnapshot!.docs.forEach((doc) {
List<dynamic> allImageData = doc["image_data"];
storeImageList = allImageData.map((i) => i.toString()).toList();
});
prefs.setStringList("imageList", storeImageList);
});
}

Flutter Web putData doesn't Put the Data

With Flutter Web, Firebase Storage, Getting an XFile from Image_Picker, I am trying to implement the putData method, (which actually executes without errors). A putFile implementation works fine for me for mobile. I need to use putData for Web.
This simplified code executes without errors, and file name, date, etc all populate in Storage, but without the actual file (9 bytes displayed as size).
I get an XFile from Image_Picker. The sample implementation from flutterfire's storage example also uses XFile and putData here.
Future<void> _startUpload(XFile file) async {
firebase_storage.FirebaseStorage _storage = firebase_storage.FirebaseStorage.instance;
firebase_storage.UploadTask? _uploadTask;
String filePath = 'filePath';
final metadata = firebase_storage.SettableMetadata(
contentType: 'image/jpeg',
);
Uint8List bytesFile = await file.readAsBytes();
final uploadTask = _storage.ref().child(filePath).putData(bytesFile, metadata);
final snapshot = await uploadTask;
final url = await snapshot.ref.getDownloadURL();
debugPrint('here is the download url: $url');
}
Just going to leave this here for future users who encounter this until the bug is fixed. The XFile method fromData isn't functioning properly as detailed here.
This was my issue. If you use cross_file or image_picker with a crop utility that required you to get an Xfile.fromData, it will fail until this is updated.

How to show the image downloaded fom the firebase storage always in a flutter application statically,can be opened and viewed on a click

How to show the image downloaded from the firebase storage always in a flutter application statically, can be opened and viewed on a click.
I have already uploaded an image from camera and gallery to firebase storage. Now I want to download the image from the firebase storage and make a provision that the images downloaded will be readily stay in the application without disappearing.
I mean when ever user visits that flutter application screen, the image or images downloaded should be shown.
Uploaded the image using using firebase storage:
final FirebaseStorage _storage =
FirebaseStorage(storageBucket: 'gs://flutter-imageupload-cb66a.appspot.com');
StorageUploadTask _uploadTask;
_startUpload() async {
String imagePath = 'DeviceImages/DeviceImage${DateTime.now()}.png';
final StorageReference storageReference = FirebaseStorage().ref().child(imagePath);
final StorageUploadTask uploadTask = storageReference.putFile(imageFile1);
await uploadTask.onComplete;
_addPathToDatabase(imagePath);
print("Image uploaded");
setState(() {
_uploadTask =
_storage.ref().child(imagePath).putFile(imageFile1);
});
}
used firebase_storage: ^3.1.6 and firebase_database:
used image_picker: ^0.6.7+17 for picking the image from camera and Gallery.
To download an image from firebase storage, try the following:
final StorageReference storageReference = FirebaseStorage().ref().child(imagePath);
final UploadTask uploadTask = storageReference.putFile(imageFile1);
uploadTask.then((res) {
res.ref.getDownloadURL();
});
UploadTask extends the Future class therefore you can use then() which registers a callback which will be called after the future returns a result. Then you will be able to get the url using the method getDownloadUrl().
Once you have the url you can use CachedNetworkImage class and do the following:
CachedNetworkImage(
imageUrl: imgUrl,
);
You need to download the package first:
https://pub.dev/packages/cached_network_image
Check the guide here on how to display images from the internet:
https://flutter.dev/docs/cookbook/images/network-image
https://flutter.dev/docs/cookbook/images/cached-images

Save the image even the application restart

I have a problem. Everytime when I search a image from my gallery for my profilepicture its work. even when I pressed the log out button and log in again there is still my profilpicture. But when I closed the app and I restart the app then the profilepicture is gone. Does anyone know how to save the URL correctly?
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;
var downUrl = await (await uploadTask.onComplete).ref.getDownloadURL();
Constants.URL_Profil_Picture = downUrl.toString();
setState(() {
print('Profile Picture uploaded');
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Profile Picture Uploaded')));
});
}
image: (_image != null) ? FileImage(
_image)
: NetworkImage(Constants.URL_Profil_Picture),
This seems the cause of the problem:
Constants.URL_Profil_Picture = downUrl.toString();
My guess it that when you restart the app, the Constants.URL_Profil_Picture is set to its hard-coded value again.
You'll need to store the URL somewhere that survives application restarts. The common approaches for that are:
Store the URL in shared preferences, or some other form of local storage. This makes the URL available only on the device where it was uploaded from.
Store the URL in a cloud database, such as Cloud Firestore or Realtime Database. This is the most common option, as it gives you the most flexibility.
Given that you're talking about user profiles: if you're using Firebase Authentication to sign in the user, and this image is their profile picture, you can also store it in the user profile.

Flutter: Restrict calling build method many times

I am implementing a chat application where users can share images. Each image is a stateful widget and each of them should get uploaded to the Firebase Storage as well.
My problem is, this flow works fine at the beginning of the app but when you upload another image, instead of the a single file, now 2 files are getting uploaded (1 new file and the file from the previous message).
I am pretty sure that this is something to do with keys so I provide an instance of UniqueKey as well but the problem is still there.
Let me explain my implementation and then provide the code:
I have 2 files; one is the chat screen, and the other one is a single message chip.
Chat screen keeps a list of message chips and does the rendering accordingly.
Message chip is stateful because, I want the user to see a progress while it is being uploaded to the server. After picking up a file from the device, an instance of message chip will get pushed to the array in the chat screen.
My code for the attach pic button in chat screen:
IconButton(
icon: Icon(Icons.attach_file),
onPressed: () async {
final File _file = await ImagePicker.pickImage(
source: ImageSource.gallery);
if (_file != null) {
//appending to the messages list
final sss = new MediaMessage(
key: UniqueKey(),
file: _file,
isImage: true,
threadId: widget._threadId,
);
setState(() {
_messages.add(sss);
});
}
},
)
and here is the code in my message chip file (including only the essentials)
void initState() {
super.initState();
//creating a file name eg: img_456985.jpg
final rand = Math.Random().nextInt(10000);
final fileExt = widget.file.path
.substring(widget.file.path.lastIndexOf('.'), widget.file.path.length);
_fileName = 'image_$rand$fileExt';
final StorageReference storeRef = FirebaseStorage.instance
.ref()
.child('threads')
.child(widget.threadId)
.child(_fileName);
final uploadTask = storeRef.putFile(widget.file);
uploadTask.events.listen((event) {
setState(() {
_uploadPercentage = event.snapshot.bytesTransferred.toDouble() /
event.snapshot.totalByteCount.toDouble();
});
print(_uploadPercentage);
});
uploadTask.onComplete.then((snapshot) {
setState(() {
_uploadStatus = UploadProgressStatus.complete;
});
});
}
Here is a demo GIF of this issue:
GIF image demo
Any suggestions/solutions would be appreciated.
Thank you
Null the file value after image uploading task might work.
like
widget.file=null
place it after uploadTask

Resources