I am getting two issues with my coding. I have created a multiple image picker that uploads all the images of the logged user into firebase image storage under the user ID. But the issue is when it downloads the image link from the storage of multiple images. It just fetches one image URL and doesn't add other URLs in the firebase database
here is my firebase database structure and storage
The Code for uploading URL into database
When you check then you can see I am using a set URL to the value but I want it to be added or create a new URL with each new image and not just update one image URL and not create other images URL. Is there anything I can do? like a loop or something or a comment to add instead of the set each URL value.
THE MULTIPLE IMAGE PICKER CODE IS HERE
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart' as firebase_storage;
import 'package:path/path.dart' as Path;
class AddImage extends StatefulWidget {
const AddImage({Key? key}) : super(key: key);
@override
_AddImageState createState() => _AddImageState();
}
class _AddImageState extends State<AddImage> {
bool uploading = false;
double val = 0;
DatabaseReference? imgRef;
late firebase_storage.Reference ref;
final List<File> _image = [];
final picker = ImagePicker();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Add Image'),
actions: [
TextButton(
onPressed: () {
setState(() {
uploading = true;
});
uploadFile().whenComplete(() => Navigator.of(context).pop());
},
child: const Text(
'upload',
style: TextStyle(color: Colors.white),
))
],
),
body: Stack(
children: [
Container(
padding: const EdgeInsets.all(4),
child: GridView.builder(
itemCount: _image.length + 1,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (context, index) {
return index == 0
? Center(
child: IconButton(
icon: const Icon(Icons.add),
onPressed: () =>
!uploading ? chooseImage() : null),
)
: Container(
margin: const EdgeInsets.all(3),
decoration: BoxDecoration(
image: DecorationImage(
image: FileImage(_image[index - 1]),
fit: BoxFit.cover)),
);
}),
),
uploading
? Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
child: const Text(
'uploading...',
style: TextStyle(fontSize: 20),
),
),
const SizedBox(
height: 10,
),
CircularProgressIndicator(
value: val,
valueColor: const AlwaysStoppedAnimation<Color>(Colors.green),
)
],
))
: Container(),
],
));
}
chooseImage() async {
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
_image.add(File(pickedFile!.path));
});
if (pickedFile?.path == null) retrieveLostData();
}
Future<void> retrieveLostData() async {
final LostData response = await picker.getLostData();
if (response.isEmpty) {
return;
}
if (response.file != null) {
setState(() {
_image.add(File(response.file!.path));
});
} else {
print(response.file);
}
}
Future uploadFile() async {
int i = 1;
for (var img in _image) {
setState(() {
val = i / _image.length;
});
ref = firebase_storage.FirebaseStorage.instance
.ref()
.child('imageAlbum/${FirebaseAuth.instance.currentUser?.uid}/${Path.basename(img.path)}');
await ref.putFile(img).whenComplete(() async {
await ref.getDownloadURL().then((value) {
imgRef?.set({'url': value});
i++;
});
});
}
}
@override
void initState() {
super.initState();
imgRef = FirebaseDatabase.instance.ref('imageUrls/${FirebaseAuth.instance.currentUser?.uid}');
}
}
SECOND PROBLEM IN DISPLAYING
I am getting these two errors because of snapshot. I am not sure is using documents is a good way or what should i use instead of the documents.
The code of Display image page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';
import 'upload_images.dart';
class ViewImagePage extends StatefulWidget {
const ViewImagePage({Key? key}) : super(key: key);
@override
_ViewImagePageState createState() => _ViewImagePageState();
}
class _ViewImagePageState extends State<ViewImagePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('View Images')),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const AddImage()));
},
),
body: StreamBuilder(
stream: FirebaseDatabase.instance.ref().child('imageUrls/${FirebaseAuth.instance.currentUser?.uid}').onValue,
builder: (context, snapshot) {
return !snapshot.hasData
? const Center(
child: CircularProgressIndicator(),
)
: Container(
padding: const EdgeInsets.all(4),
child: GridView.builder(
itemCount: snapshot.data.documents.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (context, index) {
return Container(
margin: const EdgeInsets.all(3),
child: FadeInImage.memoryNetwork(
fit: BoxFit.cover,
placeholder: kTransparentImage,
image: snapshot.data.documents[index].get('url')),
);
}),
);
},
),
);
}
}
Help me with any of the two problems if you have any idea why it is occuring. Thanks a lot in advance.