이번에는 image picker 에서 선택한 이미지를 Firebase Storage 에 저장하고 저장위치를 알아내는 부분을 구현해보겠습니다.
개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1
필요한 패키지는 아래와 같습니다.
firebase_storage: ^10.3.5
패키지를 추가하고 Storage 의 Rules 부분을 수정해야 한다. 수정하지 않으면 데이터를 업로드 할 수 없다.
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
./src/models/item_model.dart - 업로드할때 중복되지 않게 키값을 조항하는 함수 추가
static String generateItemKey(String uid) {
String timeInMilli = DateTime.now().millisecondsSinceEpoch.toString();
return '${uid}_$timeInMilli';
}
./src/repo/image_storage.dart 신규생성
import 'dart:typed_data';
import 'package:firebase_storage/firebase_storage.dart';
import '../utils/logger.dart';
class ImageStorage {
static Future<List<String>> uploadImage(List<Uint8List> images, String itemKey) async {
// 이미지 타입지정,
var metaData = SettableMetadata(contentType: 'image/jpeg');
List<String> downloadUrls = [];
for (var i = 0; i < images.length; i++) {
// 저장위치 설정 ref('images/$itemKey/$i.jpg')
// 참고자료 - "https://firebase.google.com/docs/storage/android/create-reference?authuser=0"
Reference ref =
FirebaseStorage.instance.ref('images/$itemKey/$i.jpg');
if (images.isNotEmpty) {
// 데이터 업로드,
await ref.putData(images[i], metaData).catchError((onError){
logger.e('picture uploading error: ' + onError.toString());
});
// 업로드 완료된 파일 위치 저장,
downloadUrls.add(await ref.getDownloadURL());
}
}
return downloadUrls;
}
}
./src/screens/input/input_screen.dart
// 이미지 업로딩 및 다운로드주소 저장
void attemptCreateItem() async {
if (FirebaseAuth.instance.currentUser == null) return;
// 완료 버튼 클릭
isCreatingItem = true;
// setState 해줘야 인디케이터가 동작한다,
setState(() {});
final String userKey = FirebaseAuth.instance.currentUser!.uid;
final String userPhone = FirebaseAuth.instance.currentUser!.phoneNumber!;
final String itemKey = ItemModel2.generateItemKey(userKey);
List<Uint8List> images = SelectImageController.to.images;
// uploading raw data and return the Urls,
List<String> downloadUrls = await ImageStorage.uploadImage(images, itemKey);
final num? price = num.tryParse(_priceController.text.replaceAll(RegExp(r'\D'), ''));
logger.d('upload finished(${downloadUrls.length}) : $downloadUrls');
Get.back();
}
// AppBar 에 옵션 추가, 이미지 저장동안 인디케이터 처리
bottom: PreferredSize(
preferredSize: Size(_size.width, 3),
child: isCreatingItem ? const LinearProgressIndicator(minHeight: 3) : Container(),
),
'Flutter > 12 Clone 'Used Goods app'' 카테고리의 다른 글
[Flutter] Clone - 당근마켓36(ItemModel upload - validators) (0) | 2022.08.19 |
---|---|
[Flutter] Clone - 당근마켓35(ItemModel upload) (0) | 2022.08.18 |
[Flutter] Clone - 당근마켓33(InputScreen - image picker/Getx) (0) | 2022.08.17 |
[Flutter] Clone - 당근마켓32(ItemModel) (0) | 2022.08.12 |
[Flutter] Clone - 당근마켓31(InputScreen - image picker upgrade) (0) | 2022.08.11 |