ExampleStorage · Database
File Upload
Pick an image from the device, upload it to Cloudflare R2, and save the URL to the user's profile in the database.
Prerequisites
Add image_picker to your pubspec.yaml and create an avatars bucket in the dashboard.
pubspec.yamlYAML
dependencies:
koolbase: ^1.4.0
image_picker: ^1.0.0Profile avatar upload
lib/screens/profile_screen.dartDart
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
String? _avatarUrl;
bool _uploading = false;
Future<void> _pickAndUpload() async {
final picker = ImagePicker();
final picked = await picker.pickImage(
source: ImageSource.gallery,
maxWidth: 800,
imageQuality: 85,
);
if (picked == null) return;
setState(() => _uploading = true);
try {
final user = await Koolbase.auth.currentUser();
final bytes = await picked.readAsBytes();
// 1. Upload to R2
await Koolbase.storage.uploadBytes(
bytes,
bucket: 'avatars',
path: 'user_${user!.id}.jpg',
contentType: 'image/jpeg',
onProgress: (sent, total) {
// Optional: show progress
},
);
// 2. Get the download URL
final url = await Koolbase.storage.getDownloadUrl(
bucket: 'avatars',
path: 'user_${user.id}.jpg',
);
// 3. Save URL to user's profile record
await Koolbase.db
.collection('profiles')
.doc(user.id)
.update({'avatar_url': url});
setState(() => _avatarUrl = url);
} finally {
setState(() => _uploading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: _uploading ? null : _pickAndUpload,
child: CircleAvatar(
radius: 50,
backgroundImage: _avatarUrl != null
? NetworkImage(_avatarUrl!)
: null,
child: _uploading
? const CircularProgressIndicator()
: (_avatarUrl == null ? const Icon(Icons.add_a_photo) : null),
),
),
const SizedBox(height: 16),
const Text('Tap to change avatar'),
],
),
),
);
}
}Load profile on startup
lib/screens/profile_screen.dartDart
@override
void initState() {
super.initState();
_loadProfile();
}
Future<void> _loadProfile() async {
final user = await Koolbase.auth.currentUser();
if (user == null) return;
final record = await Koolbase.db
.collection('profiles')
.doc(user.id)
.get();
setState(() => _avatarUrl = record.data['avatar_url']);
}