i want to get the image link in firestore - flutter

i want to get the image link in database, but i get the image url in other document and (name & etc) in other document.
database.collection("car").add({
"item Name": nameText.text,
"item Price": priceText.text,
"seller Number": cellNoText.text,
"seller add": addText.text,
"image 1 Url": await uploadPic()
.then((value) async {
DocumentReference docRef = Firestore
.instance
.collection("car")
.document();
await docRef.setData(
{"image 1 Url": value},
merge: true);
}),
});
this is the function to upload the image to firebase storage
uploadPic() async {
String fileName = path.basename(_image1.path);
StorageReference reference = storage.ref().child(fileName);
StorageUploadTask uploadTask = reference.putFile(_image1);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
imageUrl1 = url;
return url;
}
can you guys help?

Your image url has been created in the wrong location because of the then of the uploadPic(), and its null in the car document because you need to call the Future function before adding it to the document:
Future uploadPic() async {
String fileName = path.basename(_image1.path);
StorageReference reference = storage.ref().child(fileName);
StorageUploadTask uploadTask = reference.putFile(_image1);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
return url;
}
Future saveData() async {
String imageUrl = await uploadPic(); //calling and adding the result to a variable before adding
database.collection("car").add({
"item Name": nameText.text,
"item Price": priceText.text,
"seller Number": cellNoText.text,
"seller add": addText.text,
"imageUrl": imageUrl,
});
}

Related

Flutter - Firebase - Delete a document without having access to it

I am trying to have access to notificationId once it gets created however the delete function deletes all the documents under this collection ('user-notifications').
Do you know what I need to change so I can remove only one document rather than all documents in this collection?
Future<String> likeAnnouncementNotification(String announcementId,
String imageUrl, String ownerUid, String uid, List liked) async {
String notificationid = const Uuid().v1();
String res = "Some error occurred";
try {
if (liked.contains(uid)) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.where("uid", isEqualTo: FirebaseAuth.instance.currentUser?.uid)
.get()
.then((value) {
value.docs.forEach((document) {
document.reference.delete();
});
});
} else {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notificationid)
.set(
{
'imageUrl': imageUrl,
'announcementId': announcementId,
'notificationid': notificationid,
'timestamp': DateTime.now(),
'type': 0,
'uid': uid
},
);
}
res = 'success';
} catch (err) {
res = err.toString();
}
return res;
}
the only thing i see that you need to specify what notification document you went to delete add it like parameter when you call likeAnnouncementNotification function
Future<String> likeAnnouncementNotification(
String announcementId,
String imageUrl,
String ownerUid,
String uid,
List liked,
) async {
String notificationid = const Uuid().v1();
String res = "Some error occurred";
try {
if (liked.contains(uid)) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.where("uid", isEqualTo: FirebaseAuth.instance.currentUser?.uid)
.get()
.then((value) {
value.docs.forEach((notification) {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notification.id) // this is the problem you need to specify what notification document you went to delete.
.delete();
});
});
} else {
FirebaseFirestore.instance
.collection('notifications')
.doc(ownerUid)
.collection('user-notifications')
.doc(notificationid)
.set(
{
'imageUrl': imageUrl,
'announcementId': announcementId,
'notificationid': notificationid,
'timestamp': DateTime.now(),
'type': 0,
'uid': uid
},
);
}
res = 'success';
} catch (err) {
res = err.toString();
}
return res;
}

No object exists at the desired reference

I am trying to get an image from the storage and use the url for a default profile picture but i am getting this error.
firebase_storage/object-not-found No object exists at the desired reference.
This is my code.
void authenticateStudent() async {
User? currentStudent;
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
await firebaseAuth
.createUserWithEmailAndPassword(
email: umailController.text.trim(),
password: passwordController.text.trim(),
)
.then((auth) {
currentStudent = auth.user;
}).catchError((onError) {
print(onError);
});
if (currentStudent != null) {
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
.then((url) {
imageUrl = url;
});
saveDataToFirestore(currentStudent!).then((value) {
Navigator.pop(context);
print("User added successfully");
});
}
}
Future saveDataToFirestore(User currentStudent) async {
FirebaseFirestore.instance
.collection("students")
.doc(currentStudent.uid)
.set({
"studentUID": currentStudent.uid,
"fname": fnameController.text.trim(),
"lname": lnameController.text.trim(),
"Mobile": phoneController.text.trim(),
"Program": selectedProgram,
"student_id": studentidController.text.trim(),
"cohort": selectedCohort,
"umail": currentStudent.email,
"profilepicture": imageUrl,
"active": active,
"status": status
});
}
The database is structured like this
This is my code.
void authenticateStudent() async {
User? currentStudent;
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
await firebaseAuth
.createUserWithEmailAndPassword(
email: umailController.text.trim(),
password: passwordController.text.trim(),
)
.then((auth) {
currentStudent = auth.user;
}).catchError((onError) {
print(onError);
});
if (currentStudent != null) {
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
.then((url) {
imageUrl = url;
});
saveDataToFirestore(currentStudent!).then((value) {
Navigator.pop(context);
print("User added successfully");
});
}
}
Future saveDataToFirestore(User currentStudent) async {
FirebaseFirestore.instance
.collection("students")
.doc(currentStudent.uid)
.set({
"studentUID": currentStudent.uid,
"fname": fnameController.text.trim(),
"lname": lnameController.text.trim(),
"Mobile": phoneController.text.trim(),
"Program": selectedProgram,
"student_id": studentidController.text.trim(),
"cohort": selectedCohort,
"umail": currentStudent.email,
"profilepicture": imageUrl,
"active": active,
"status": status
});
}
The database is structured like this
Your code says:
FirebaseStorage.instance
.ref()
.child('profile')
.getDownloadURL()
But in the screenshot, the file is called profile.png. The path must match completely and exactly, so:
FirebaseStorage.instance
.ref()
.child('profile.png')
.getDownloadURL()

How to store image in flutter firestore and display it

Trying to store image in books collection flutter but not letting me store and retrieve it later. Please help me trace the bug. Problem is with coverImage that is not letting me store the image URL in firebase so that the image could be displayed when its fetched later.
if (name != null &&
price != null &&
author != null &&
description != null &&
discountpercentage != null &&
rating != null) {
if (action == 'create') {
await books_collection.add({
"name": name,
"price": price,
"author": author,
"description": description,
"discountpercentage": discountpercentage,
"rating": rating,
"createdAt": Timestamp.now(),
"coverImage": Timestamp.now(),
// "url": uploadFilterImage()
});
}
if (action == 'update') {
// Update the product
await books_collection.doc(documentSnapshot!.id).update({
"name": name,
"price": price,
"author": author,
"description": description,
"discountpercentage": discountpercentage,
"rating": rating,
"createdAt": Timestamp.now(),
"coverImage": uploadFilterImage()
});
Future<String> uploadFilterImage() async {
String url = "";
final ImagePicker _picker = ImagePicker();
XFile? image = await _picker.pickImage(source: ImageSource.gallery);
Uint8List fileBytes = await image!.readAsBytes();
if (fileBytes != null) {
final _firebaseStorage = FirebaseStorage.instance;
var name = Timestamp.now().millisecondsSinceEpoch;
print("$name");
var snapshot = _firebaseStorage.ref().child('$name');
print("$name");
TaskSnapshot task = await snapshot.putData(
fileBytes,
SettableMetadata(contentType: 'image/jpeg'),
);
url = await task.ref.getDownloadURL();
if (url.isNotEmpty) {
Get.snackbar("successfull", "image uploaded");
}
}
return url;
}
You need to await the uploadFilterImage() call in order to process the async function and not return a Future, but return the final value instead. The same is true for both your create and update cases.
await books_collection.doc(documentSnapshot!.id).update({
"name": name,
"price": price,
"author": author,
"description": description,
"discountpercentage": discountpercentage,
"rating": rating,
"createdAt": Timestamp.now(),
"coverImage": await uploadFilterImage() // here
});

PageView.Builder in Flutter The getter 'length' was called on null. Receiver: null Tried calling: length

when use response from API then show error
The getter 'length' was called on null.
Receiver: null
Tried calling: length
here is my API code
var url =
"https://domain.php";
var res;
var splashs;
void initState() {
super.initState();
fetchData();
}
fetchData() async {
res = await http.get(url);
splashs = jsonDecode(res.body);
setState(() {});
}
while use List then code working properly
List<Map<String, String>> splashs = [
{
"header": "Flatros",
"text": "Welcome to Flatros, Let’s shop!",
"image_name": "assets/images/splash_1.png"
},
{
"header": "Shopping",
"text":
"We help people conect with store \naround United State of America",
"image_name": "assets/images/splash_2.png"
},
{
"header": "Multi Category",
"text": "FInal Screen",
"image_name": "assets/images/splash_3.png"
},
];
May be you need to convert your data into List or Array
List splashs = new List();
fetchData() async {
res = await http.get(url);
final data = jsonDecode(res.body);
for (var i in data) {
splashs.add(i); // Create a list and add data one by one
}
setState(() {});
}

How do i convert a String to a List<Map<String,String>>

I have a list which contains several keys and values, which are then mapped into a DataTable to be displayed.
List<Map<String, String>> listOfColumns = [
{"Name": "John", "Number": "1", "State": " "},
{"Name": "Brad", "Number": "2", "State": " "},
{"Name": "Ryan", "Number": "3", "State": " "},
{"Name": "Grant", "Number": "4", "State": " "},
];
Now, i want the data in the data table to be saved. So I simply used the File IO system i created an asynchronous function called _save() and _read(), in _save() i converted listOfColumns to a string.
_read() async {
try {
final directory = await getExternalStorageDirectory();
final file = File('${directory.path}/my_file.txt');
text = await file.readAsString();
} catch (e) {
print("Couldn't read file");
}
}
_save() async {
final directory = await getExternalStorageDirectory();
final file = File('${directory.path}/my_file.txt');
final List<Map<String, String>> data = listOfColumns;
await file.writeAsString(data.toString());
print('saved');
}
Now when it comes to reading the data from the file, here's the thing - How do i actually turn the variable text back into List<Map<String,String>>? Im totally lost on how to achieve this. Any help is highly appreciated. Thanks.
You should actually save it as JSON in the first place (using jsonEncode and then you can easily convert it back:
Future<void> _save() async {
...
final jsonString = jsonEncode(listOfColumns);
await file.writeAsString(jsonString);
}
Now, you can easily load your data using jsonDecode:
Future<void> _read() async {
...
final decoded = jsonDecode(await file.readAsString()) as List;
listOfColumns = decoded.cast<Map<String, dynamic>>()
.map((map) => map.cast<String, String>()).toList();
}