1
+ import 'dart:io';
1
2
import 'package:cloud_firestore/cloud_firestore.dart';
3
+ import 'package:firebase_auth/firebase_auth.dart';
4
+ import 'package:firebase_storage/firebase_storage.dart';
5
+ import 'package:image_picker/image_picker.dart';
6
+ import 'package:flutter/material.dart';
2
7
3
8
class RegisteredCrop {
9
+ String? documentId; // New field to store Firestore document ID
4
10
String cropName;
5
11
String minBid;
6
12
String totalWeight;
7
13
String state;
8
14
String phoneNumber;
9
15
DateTime timestamp;
16
+ List<String> imageUrls; // Added to store image URLs
10
17
11
18
// Constructor
12
19
RegisteredCrop({
20
+ this.documentId, // Optional since it's not always available during creation
13
21
required this.cropName,
14
22
required this.minBid,
15
23
required this.totalWeight,
16
24
required this.state,
17
25
required this.phoneNumber,
18
26
required this.timestamp,
27
+ required this.imageUrls, // Pass image URLs
19
28
});
20
29
21
30
// Factory constructor to create an instance from Firestore Document
22
- factory RegisteredCrop.fromFirestore(Map<String, dynamic> firestoreData) {
31
+ factory RegisteredCrop.fromFirestore(DocumentSnapshot doc) {
32
+ Map<String, dynamic> firestoreData = doc.data() as Map<String, dynamic>;
23
33
return RegisteredCrop(
34
+ documentId: doc.id, // Use the Firestore document ID
24
35
cropName: firestoreData['cropName'] ?? '',
25
36
minBid: firestoreData['minBid'] ?? '',
26
37
totalWeight: firestoreData['totalWeight'] ?? '',
27
38
state: firestoreData['state'] ?? '',
28
39
phoneNumber: firestoreData['phoneNumber'] ?? '',
29
40
timestamp: (firestoreData['timestamp'] as Timestamp).toDate(),
41
+ imageUrls: List<String>.from(firestoreData['imageUrls'] ?? []), // Fetch image URLs
30
42
);
31
43
}
32
44
@@ -39,6 +51,7 @@ class RegisteredCrop {
39
51
'state': state,
40
52
'phoneNumber': phoneNumber,
41
53
'timestamp': Timestamp.fromDate(timestamp),
54
+ 'imageUrls': imageUrls, // Save image URLs
42
55
};
43
56
}
44
57
@@ -57,4 +70,112 @@ class RegisteredCrop {
57
70
print('Failed to register crop: $e');
58
71
}
59
72
}
73
+
74
+ // Method to upload images and return their URLs
75
+ static Future<List<String>> _uploadImages(List<XFile>? imageFiles) async {
76
+ List<String> imageUrls = [];
77
+ try {
78
+ User? currentUser = FirebaseAuth.instance.currentUser;
79
+ if (currentUser == null) {
80
+ print('No authenticated user found');
81
+ return imageUrls;
82
+ }
83
+
84
+ // Ensure there are files to upload
85
+ if (imageFiles != null && imageFiles.isNotEmpty) {
86
+ for (var file in imageFiles) {
87
+ File imageFile = File(file.path);
88
+
89
+ // Check if the file exists
90
+ if (!await imageFile.exists()) {
91
+ print('File does not exist: ${file.path}');
92
+ continue; // Skip this file and move to the next
93
+ }
94
+
95
+ // Generate a unique file name for Firebase Storage
96
+ String fileName = 'crop_images/${currentUser.uid}/${DateTime.now().millisecondsSinceEpoch}.jpg';
97
+
98
+ try {
99
+ // Firebase Storage reference to upload the image
100
+ Reference storageReference = FirebaseStorage.instance.ref().child(fileName);
101
+
102
+ // Upload task
103
+ UploadTask uploadTask = storageReference.putFile(
104
+ imageFile,
105
+ SettableMetadata(contentType: 'image/jpeg'),
106
+ );
107
+
108
+ // Wait for the upload task to complete
109
+ TaskSnapshot snapshot = await uploadTask;
110
+
111
+ // Retrieve the download URL after upload
112
+ String downloadUrl = await snapshot.ref.getDownloadURL();
113
+
114
+ // Add the image URL to the list
115
+ imageUrls.add(downloadUrl);
116
+ print('Successfully uploaded: $downloadUrl');
117
+ } on FirebaseException catch (e) {
118
+ // Handle Firebase errors
119
+ print('Firebase Storage Error: ${e.code} - ${e.message}');
120
+ }
121
+ }
122
+ } else {
123
+ print('No images selected for upload');
124
+ }
125
+ } catch (e) {
126
+ // Handle unexpected errors
127
+ print('Unexpected error in image upload: $e');
128
+ }
129
+
130
+ return imageUrls;
131
+ }
132
+ }
133
+
134
+ // Function to handle crop registration
135
+ void _registerCrop(BuildContext context, List<XFile>? _imageFiles, TextEditingController _minBidController, TextEditingController _totalWeightController, TextEditingController _phoneNumberController, String? _selectedCrop, String? _selectedState) async {
136
+ String cropName = _selectedCrop ?? 'Not Selected';
137
+ String minBid = _minBidController.text;
138
+ String totalWeight = _totalWeightController.text;
139
+ String address = _selectedState ?? 'Not Selected';
140
+ String phoneNumber = _phoneNumberController.text;
141
+
142
+ // Get the current user ID from FirebaseAuth
143
+ String userId = FirebaseAuth.instance.currentUser?.uid ?? '';
144
+
145
+ print('Crop Name: $cropName');
146
+ print('Min Bid: $minBid');
147
+ print('Total Weight (Kg): $totalWeight');
148
+ print('Address (State): $address');
149
+ print('Phone Number: $phoneNumber');
150
+ print('User ID: $userId'); // Print the user ID
151
+ print('Image Files: $_imageFiles');
152
+
153
+ // Upload images and get their URLs
154
+ List<String> imageUrls = await RegisteredCrop._uploadImages(_imageFiles);
155
+
156
+ try {
157
+ // Create RegisteredCrop instance with the image URLs
158
+ RegisteredCrop newCrop = RegisteredCrop(
159
+ cropName: cropName,
160
+ minBid: minBid,
161
+ totalWeight: totalWeight,
162
+ state: address,
163
+ phoneNumber: phoneNumber,
164
+ timestamp: DateTime.now(),
165
+ imageUrls: imageUrls, // Pass image URLs to RegisteredCrop
166
+ );
167
+
168
+ // Save data to Firestore
169
+ await newCrop.saveToFirestore();
170
+
171
+ print('Crop registration successful!');
172
+ ScaffoldMessenger.of(context).showSnackBar(
173
+ const SnackBar(content: Text('Crop registration successful!')),
174
+ );
175
+ } catch (e) {
176
+ print('Failed to register crop: $e');
177
+ ScaffoldMessenger.of(context).showSnackBar(
178
+ const SnackBar(content: Text('Failed to register crop.')),
179
+ );
180
+ }
60
181
}
0 commit comments