I want to create a subcollection inside already existing users document, the subcollection will be name "collection" and the collection contain collectionName and imageUrl.
Cloud Firestore flow
/users/user-doc-id/collection/collection-doc-id
Here is my add_new_collection.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:ukk/constants/color_constant.dart';
class AddNewCollection extends StatefulWidget {
const AddNewCollection({Key? key}) : super(key: key);
@override
State<AddNewCollection> createState() => _AddNewCollectionState();
}
class _AddNewCollectionState extends State<AddNewCollection> {
File? _image;
final _picker = ImagePicker();
String url = "";
//Editing Controllers
final collectionNameController = TextEditingController();
Future getImageFromGallery() async {
final pickedFile = await _picker.pickImage(source: ImageSource.gallery);
final File image = File(pickedFile!.path);
setState(() {
_image = image;
});
}
uploadCollection() async {
var imageFile = FirebaseStorage.instance
.ref()
.child("collectionImage")
.child(basename(_image!.path));
UploadTask task = imageFile.putFile(_image!);
TaskSnapshot snapshot = await task;
//for download
url = await snapshot.ref.getDownloadURL();
await FirebaseFirestore.instance.collection('collection').doc().set({
'imageUrl': url,
'collectionName': collectionNameController.text,
});
print(url);
}
@override
Widget build(BuildContext context) {
final fileName =
_image != null ? basename(_image!.path) : 'No Image Selected';
final addNewCollection = Material(
elevation: 5,
borderRadius: BorderRadius.circular(50),
child: Container(
width: MediaQuery.of(context).size.width,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: kGreenColor,
),
child: Material(
borderRadius: BorderRadius.circular(50),
color: Colors.transparent,
child: Center(
child: MaterialButton(
child: Text(
"Add New Collection",
textAlign: TextAlign.center,
style: GoogleFonts.dongle(
fontSize: 28,
color: kWhiteColor,
fontWeight: FontWeight.bold,
),
),
padding: const EdgeInsets.fromLTRB(20, 10, 20, 15),
minWidth: MediaQuery.of(context).size.width,
onPressed: () {
uploadCollection();
// Adding the name of the collection and the image to the Firebase storage and firestore,
// then navigating to the collection_page.dart,
// and also displaying the result on colletion_page.dart
// with the shape of a card from card_collection.dart
},
),
),
),
),
);
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
appBar: AppBar(
title: Text(
"New Collection",
style: GoogleFonts.dongle(
fontSize: 40,
color: kWhiteColor,
),
),
backgroundColor: kDarkBlue,
elevation: 0,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: kWhiteColor,
),
onPressed: () {
//passing this to our root
Navigator.of(context).pop();
},
),
),
body: Form(
child: Stack(
children: [
SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 25,
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://firebasestorage.googleapis.com/v0/b/flutterbricks-public.appspot.com/o/backgrounds/gradienta-7brhZmwXn08-unsplash.jpg?alt=media&token=ea7ee065-0bb3-4184-8baf-9188d268f075"),
fit: BoxFit.fill,
),
),
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
InkWell(
onTap: () {
getImageFromGallery();
},
child: CircleAvatar(
radius: 100,
backgroundColor: kWhiteColor,
backgroundImage: _image == null
? const AssetImage("")
: FileImage(File(_image!.path))
as ImageProvider,
),
),
const SizedBox(height: 5),
Text(
fileName,
style: const TextStyle(fontSize: 16),
),
const SizedBox(height: 40),
const Text(
'Collection Name',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
TextField(
autofocus: false,
controller: collectionNameController,
decoration: InputDecoration(
contentPadding:
const EdgeInsets.fromLTRB(20, 15, 20, 15),
hintText: "Example: My Hotwheels",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
const SizedBox(
height: 20,
),
addNewCollection,
],
),
),
)
],
),
),
],
),
),
),
);
}
}
After that I want to get the subcollection and display it as a custom card that I made
import 'package:flutter/material.dart';
import 'package:ukk/constants/color_constant.dart';
class CardCollection extends StatelessWidget {
const CardCollection({Key? key}) : super(key: key);
final double _borderRadius = 24.0;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
print('card pressed');
},
child: Container(
height: 150,
width: 350,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(_borderRadius),
gradient: LinearGradient(
colors: const [kLightRedColor, kLightOrange],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
boxShadow: const [
BoxShadow(
color: kDarkGreyColor,
blurRadius: 12,
offset: Offset(0, 6),
),
],
),
child: Column(
children: [
Positioned.fill(
child: Row(
children: [
Container(
margin: EdgeInsets.all(10),
width: 80.0,
height: 80.0,
decoration: BoxDecoration(
color: Colors.grey[50],
border: Border.all(color: Colors.transparent),
shape: BoxShape.rectangle,
),
child: Image.asset(
'assets/images/bag_1.png',
width: 50,
height: 50,
fit: BoxFit.fill,
),
),
GestureDetector(
onTap: () {
print('title pressed');
},
child: Container(
alignment: Alignment.topCenter,
margin: EdgeInsets.only(left: 16),
child: Text(
'Put Your Title Here',
style: TextStyle(
color: kWhiteColor,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
Positioned.fill(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
width: 10,
),
IconButton(
onPressed: () {
print('Delete Button Pressed');
//write onpressed function here
},
icon: Icon(
Icons.delete_forever,
size: 30,
color: kWhiteColor,
),
),
IconButton(
onPressed: () {
print('Edit Button Pressed');
//write onpressed function here
},
icon: Icon(
Icons.edit,
size: 30,
color: kWhiteColor,
),
),
],
),
)
],
),
),
);
}
}
If you need more source code, let me know
CodePudding user response:
Given that your collection is just a reference , you might want to add its id to the document such that collectionName,imageUrl,collectionId
to simplify lets refactor your collections to this
/users/user-doc-id/collection_references/collection-doc-id
- users
- user1
- user2 -collection_references
- collection1
- collection2
when creating the collection you can query your collection_references
and using the collectionId
you can now create new collections.
/users/user-doc-id/collectionId
notice I used collectionid to make it unique