how to call a method from another dart file? - flutter

in my programme i want to call the same path inside a methode called getPhoto()=>upload(statefulwidget) to other file or statefulwidget
Future getPhoto() async{
FirebaseFirestore fearbase = FirebaseFirestore.instance;
Reference ref=FirebaseStorage.instance
.ref()
.child("${widget.user}/ProfileData")
.child("Url_$postId");
await ref.putFile(file!);
downloadUrl=await ref.getDownloadURL();
// upload image to firestore
var list=[];
await fearbase.collection("users").doc(widget.user)
.collection("PostData").doc(ido)
.set({"PostUrl":downloadUrl,"ownerName":loggedInUser.username,"userId":loggedInUser.uid,"timestemp":postId,"PostId":ido,"like":FieldValue
.arrayUnion(list)})
.whenComplete(() => Fluttertoast.showToast(msg: "Image Uploaded successfully .i."));
// .then((DocumentReference ido) => ido.update({"PostId":ido.id}))
}
more specifically i want to get like field path from the other file

There are multiple ways to do this.
But the simple one is you should create a class and define this method within the class.
class Demo {
static void getPhoto() {
print("photo");
}
}
Then your can access it like
Demo.getPhoto()

You can use callback function to solve this.
Future<String> getPhoto() async {
Reference ref = FirebaseStorage.instance
.ref()
.child("${widget.user}/ProfileData")
.child("Url_$postId");
await ref.putFile(file!);
return await ref.getDownloadURL();
// upload image to firestore
// .then((DocumentReference ido) => ido.update({"PostId":ido.id}))
}
Future upload(String downloadUrl) async {
FirebaseFirestore firebase = FirebaseFirestore.instance;
var list = [];
await firebase.collection("users").doc(widget.user)
.collection("PostData").doc(ido)
.set({
"PostUrl": downloadUrl,
"ownerName": loggedInUser.username,
"userId": loggedInUser.uid,
"timestemp": postId,
"PostId": ido,
"like": FieldValue
.arrayUnion(list)
})
.whenComplete(() => Fluttertoast.showToast(msg: "Image Uploaded successfully .i."));
}
In usage, you can pass the function as follows
getPhoto().then(upload);
Or
final downloadUrl = await getPhoto();
await upload(downloadUrl);

Related

Why is (list.length == otherList.length) showing false - Flutter

I have a List<File> imageFiles made up of files that a user selects and when they press submit, each of the files is uploaded to the collection in Firebase Storage. For each one, the downloadUrl is added to another list uploadedImages. I cannot upload the document to Firestore until all the downloadUrls are added to the uploadedImages list so I used an if statement if (imageFiles.length == uploadedImages.length) {<upload document>}. The problem is, in those lists are not the same length until the forEach block completes, and even then it doesn't return true. I confirmed that all the files are uploaded to Firebase Storage and printed the uploadedImages so I know they are eventually the same length but don't know how to make the if statement recognize that. Here is my current code:
List<String> uploadedUrls = [];
/// Uploads each file and adds its URL
imageFiles.forEach((file) async {
String fileName = '${UniqueKey()}_post.png';
TaskSnapshot uploadTask = await FirebaseStorage.instance
.ref()
.child('/${user.uid}/posts/$postId/$fileName')
.putFile(file);
String url = await uploadTask.ref.getDownloadURL();
setState(() {
uploadedUrls.add(url);
});
print(uploadedUrls);
});
/// Uploads post if all files and URLs are added *NOT WORKING*
if (imageFiles.length == uploadedUrls.length) {
Post post =
Post(postId, uploadedUrls, user.uid, profile, location, Timestamp.now());
try {
FirebaseFirestore.instance
.collection('users')
.doc(user.uid)
.collection('posts')
.doc(postId)
.set(post.toJson()).then((value) {
setState(() {
_isLoading = false;
});
});
} on FirebaseAuthException {
setState(() {
_isLoading = false;
});
}
}
Because you are running an asynchronous function in forEach,it won’t wait until the task is completed. So you can either move the if condition inside the forEach’s callback below the setState or use a parent function as wrapper for both them, and it should await the first call
imageFiles.forEach((file) async {
String fileName = '${UniqueKey()}_post.png';
TaskSnapshot uploadTask = await FirebaseStorage.instance
.ref()
.child('/${user.uid}/posts/$postId/$fileName')
.putFile(file);
String url = await uploadTask.ref.getDownloadURL();
setState(() {
uploadedUrls.add(url);
});
if (imageFiles.length == uploadedUrls.length) {
....
});
or extract the forEach loop into a async function
void addDownloafUrls() asyn {
imageFiles.forEach((file) async { ... });
}
// And you can await this function
addDownloafUrls().then(() {
if (imageFiles.length == uploadedUrls.length) {...}
})

uploading multiple xfiles to firebase storage

I am trying to upload multiple (max 5) xfiles images (image_picker library) to firebase storage. currently, it uploads only one with the below method:
Future<void> addProduct({
BuildContext? ctx,
String? proName,
String? productDescription,
double? count,
double? price,
required List<XFile> images
}) async {
try {
var imageUrls = await Future.wait(images.map((_image) =>
uploadFile(_image)));
await firestore
.collection(outletsCollection)
.doc(_currentUserOutletId)
.set({
products: FieldValue.arrayUnion([
{
productId: Uuid().v4(),
productName: proName,
prodDesc: productDescription,
countInStock: count,
productPrice: price,
productImg: FieldValue.arrayUnion([imageUrls]),
}
]),
});
} catch (err) {
String errMsg = "error blahblah";
errorDialog(ctx!, errMsg);
}
notifyListeners();
}
for the uploadFile method i tried using images.forEach() instead of .map(), but it gave me void type error. uploadFile method:
Future<String> uploadFile(XFile _image) async {
var storageReference = storage
.ref()
.child('product_images')
.child(_currentUserOutletId!)
.child(Uuid().v4());
final metadata = SettableMetadata(
contentType: 'image/jpeg',
customMetadata: {'picked-file-path': _image.path},
);
if (kIsWeb) {
await storageReference.putData(await _image.readAsBytes(), metadata);
} else {
await storageReference.putFile(io.File(_image.path), metadata);
}
return await storageReference.getDownloadURL();
}
so, at the end only one image is uploaded and addProduct() does not add product to firestore database. log in android studio returns nothing. I couldn't find a method that would work with the xfile. help appreciated very much!
List<XFile> _imageFileList;
try{
final pickedFile = await _picker.pickMultiImage();
setState(() {
_imageFileList = pickedFile;
_imageFileList.forEach((element) async {
firebase_storage.FirebaseStorage storage = firebase_storage.FirebaseStorage.instance;
var date = DateTime.now().millisecondsSinceEpoch;
try {
setState(() {
_loading = true;
});
firebase_storage.UploadTask task = firebase_storage.FirebaseStorage.instance.ref('uploads/photos/'+date.toString()+'_image.png').putData(await element.readAsBytes(), SettableMetadata(contentType: 'image/jpeg'));
await storage.ref('uploads/file-to-upload.png').putData(await element.readAsBytes(), SettableMetadata(contentType: 'image/jpeg'));
firebase_storage.TaskSnapshot downloadUrl = (await task);
String url = (await downloadUrl.ref.getDownloadURL());
// print(url.toString());
} on FirebaseException catch (e) {
// e.g, e.code == 'canceled'
setState(() {
_loading = false;
});
}
});
try this way using image_picker plugin. You can get url after image upload and you have yo it in your data.

How to get Download URL from Firebase Storage in flutter

The Following Code is used to Upload any image from gallery/Camera to Firebase storage. I was successful in uploading the image to storage along with meta data. Now the problem is I am not able to get the download URL of the uploaded image. Tried a lot but didn't find any solution.
FirebaseStorage storage = FirebaseStorage.instance;
final picker = ImagePicker();
PickedFile pickedImage;
File imageFile;
Future<void> _upload(String inputSource) async {
try {
pickedImage = await picker.getImage(
source: inputSource == 'camera'
? ImageSource.camera
: ImageSource.gallery,
maxWidth: 1920);
final String fileName = path.basename(pickedImage.path);
imageFile = File(pickedImage.path);
try {
// Uploading the selected image with some custom meta data
await storage.ref(fileName).putFile(
imageFile,
SettableMetadata(
customMetadata: {
'uploaded_by': 'A bad guy',
'description': 'Some description...'
},
),
);
// Refresh the UI
setState(() {});
} on FirebaseException catch (error) {
print(error);
}
} catch (err) {
print(err);
}
}
Hope You're Doing Well …
You Can Try This Method To Get The URL Of The Image(Any File) From Firebase Storage To Firebase Store And Then You Can Retrieve Image .
class _UploadAdState extends State<UploadAdPage> {
final formKey = GlobalKey<FormState>();
File _myimage;
String imgUrl;
Future getImage1(File chosenimage) async {
PickedFile img =
await ImagePicker.platform.pickImage(source: ImageSource.gallery);
if (chosenimage == null) return null;
File selected = File(img.path);
setState(() {
_myimage = chosenimage;
});
}
// changing the firestore rules and deleteing if request.auth != null;
sendData() async {
// to upload the image to firebase storage
var storageimage = FirebaseStorage.instance.ref().child(_myimage.path);
UploadTask task1 = storageimage.putFile(_myimage);
// to get the url of the image from firebase storage
imgUrl1 = await (await task1).ref.getDownloadURL();
// you can save the url as a text in you firebase store collection now
}
}
I am using in my app this function. Pass image file and download with getDownloadUrl .
Future <String> _uploadphotofile(mFileImage) async {
final Reference storageReference = FirebaseStorage.instance.ref().child("products");
UploadTask uploadTask = storageReference.child("product_$productId.jpg").putFile(imgfile);
String url = await (await uploadTask).ref.getDownloadURL();
return url;
}

Can't get a proper URL when Image from Storage Firebase is linked to CloudFirestore

I cant get a valid URL to retrieve in my method when images are linked to CloudFirestore from Storage in Firebase:
Future uploadImage(BuildContext context) async {
String fileName = basename(_imageFile.path);
Reference firebaseStorageRef =
FirebaseStorage.instance.ref().child('ifprofile/$fileName');
UploadTask uploadTask = firebaseStorageRef.putFile(_imageFile);
TaskSnapshot taskSnapshot = await uploadTask.whenComplete(() {
var firebaseUser = FirebaseAuth.instance.currentUser;
FirebaseFirestore.instance.collection('/userProfile').add({
"imageUrl": _imageFile.path,
});
FirebaseFirestore.instance
.collection('/influencerUser')
.doc(firebaseUser.uid)
.update({
// All fields you want to update in a document
'imageUrl': IfUserProfile.imageUrl,
});
// Finish to Link images to Cloud Firestore
});
taskSnapshot.ref
.getDownloadURL()
.then((value) => print("Image uploaded: $value"));
}
into cloud firestore I get URL like this:
/data/user/0/it.test.testapp/cache/image_picker5217031945896769637.jpg
any input please?
try to modify ur code a but like this
final url = await taskSnapshot.ref
.getDownloadURL();
then take that url and put it in your firestore db
here is some code
final storageRef = FirebaseStorage.instance.ref('$folderName/$imagename');
final uploadTaskSnapshot = await storageRef.put(image).future;
final imageUri = await uploadTaskSnapshot.ref.getDownloadURL();

How to upload a image url downloaded from firebase storage to firestore document for newly registered user?

I have made it till uploading the image to firebase storage and download the url.Here, I need to store the newly registered user information in an Firestore document. I am storing some details one of those is the image URL downloaded from firebase storage.
Now, I need to assign the downloaded Url to Firestore to access it in my dart pages.
uploadImage() async {
var random = Random(25);
final StorageReference fireref = FirebaseStorage.instance
.ref()
.child('profilepics/${random.nextInt(5000).toString()}.jpg');
StorageUploadTask task = fireref.putFile(profilepic);
StorageTaskSnapshot snapshottask = await task.onComplete;
String downloadUrl = await snapshottask.ref.getDownloadURL();
if (downloadUrl != null) {
userManagement.addProfilePic(downloadUrl.toString()).then((val) {
Navigator.of(context).pushReplacementNamed('/twelf');
});
}
}
The above is the code of getting the image url from firebase storage.And, If you can see I have called a method addProfilePic to add the downloaded URL to firestore. And the method is,
Future addProfilePic(picUrl) async {
//---
}
What Should i write in this method to upload url to firestore. I am not able to understand.
Additional code for understanding:
class UserManagement {
storeNewUser(user, context) {
Firestore.instance.collection('/userdetails').add({
'Email': user.email,
'uid': user.uid,
'displayName': user.fullname,
'photoUrl': user.photoUrl
}).then((value) {
Navigator.of(context).pop();
Navigator.of(context).pushReplacementNamed('/selectpic');
}).catchError((e) {
print(e);
});
}
And the below code is near registration the final code that upload data to firestore:
final String userId = await widget.auth
.createUserWithEmailAndPassword(_email, _password)
.then((signedInUser) async {
var userUpdateInfo = new UserUpdateInfo();
userUpdateInfo.displayName = _fullname;
userUpdateInfo.photoUrl = _imageurl;
//'https://cdn.mos.cms.futurecdn.net/QjuZKXnkLQgsYsL98uhL9X-1024-80.jpg';
final user = await FirebaseAuth.instance.currentUser();
user.updateProfile(userUpdateInfo).then((user) {
FirebaseAuth.instance
.currentUser()
.then(
(user) => {UserManagement().storeNewUser(user, context)})
.catchError((e) {
print(e);
});
}).catchError((e) {
print(e);
});
}).catchError((e) {
print(e);
});
print('Registered user: $userId');
}
Try this:
Future<String> uploadImage(profilepic) async {
StorageUploadTask uploadTask = storageRef.child("profilepics/${random.nextInt(5000).toString()}.jpg").putFile(profilepic);
StorageTaskSnapshot storageTaskSnapshot = await uploadTask.onComplete;
String downlaodUrl = await storageTaskSnapshot.ref.getDownloadURL();
return downlaodUrl;
}
// String imageUrl = await uploadImage(profilepic); You can store the value of imageUrl in firebase document.
Firestore.instance.collection('/userdetails').add({
// All fields you want to have in a document
'photoUrl': imageUrl; // use the image url variable
});
/// To update a currentUser document
Firestore.instance.collection('/userdetails')
.document(your_user_document_name_here)
.updateData({
// All fields you want to update in a document
'photoUrl': imageUrl; // use the image url variable
});