Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- Snapshot
- swift 문법
- Navigator
- reference
- switch
- borderRadius
- changenotifierprovider
- transform
- signout
- ListView.builder
- divider
- Swift
- 문법
- user
- consumer
- snackbar
- platformexception
- Camera
- runTransaction
- controller
- Firebase
- setstate
- changenotifier
- Stream
- datetime
- globalkey
- provider
- multiprovider
- permission
- enum
Archives
- Today
- Total
코딩하는 제리
[Flutter/Project](Instagram Clone) 포스트 데이터 업로드/업데이트 파일 작성 본문
Flutter/Project_InstaClone(완)
[Flutter/Project](Instagram Clone) 포스트 데이터 업로드/업데이트 파일 작성
JerryCho 2021. 3. 1. 20:34StatefulWidget으로 변경한 후 TextEditingController 작성
소스코드 및 pubspec.yaml
// models/repo/post_network_repository.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_project_IJ/constants/firestore_keys.dart';
/*
포스트 데이터 업로드 과정
1. post reference를 가져옴(생성)
2. 어떤 포스트가 해당 유저에 포함되어 있는지 user reference를 가져옴
3. post collection과 user collection 두가지를 업데이트 해야하기에 transaction 사용.
4. user data에 postKey를 업데이트
5. post reference를 통해 post data를 업로드
*/
class PostNetworkRepository {
Future<void> createNewPost(
String postKey, Map<String, dynamic> postData) async {
// 1. post reference를 가져옴(생성)
final DocumentReference postRef =
FirebaseFirestore.instance.collection(COLLECTION_POSTS).doc(postKey);
// post reference를 통해 해당 document의 snapshot을 가져옴.
final DocumentSnapshot postSnapshot = await postRef.get();
// 2. 어떤 포스트가 해당 유저에 포함되어 있는지 user reference를 가져옴
final DocumentReference userRef = FirebaseFirestore.instance
.collection(COLLECTION_USERS)
.doc(postData[KEY_USERKEY]);
// 3. transaction -> 데이터 업로드에 하나라도 실패하면 이전의 데이터로 바꿔줌.
return FirebaseFirestore.instance.runTransaction((Transaction tx) async {
// 해당 postSnapshot이 존재하지 않으면
if (!postSnapshot.exists) {
// 4. 포스트 데이터 업로드
await tx.set(postRef, postData);
// 5. user의 mypost를 업데이트
// user reference에 postKey 추가
await tx.update(userRef, {
KEY_MYPOSTS: FieldValue.arrayUnion([postKey])
});
}
});
}
}
PostNetworkRepository postNetworkRepository = PostNetworkRepository();
// screens/share_post_screen.dart
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_project_IJ/constants/common_size.dart';
import 'package:flutter_project_IJ/constants/screen_size.dart';
import 'package:flutter_project_IJ/models/firestore/post_model.dart';
import 'package:flutter_project_IJ/models/firestore/user_model.dart';
import 'package:flutter_project_IJ/models/user_model_state.dart';
import 'package:flutter_project_IJ/repo/image_network_repository.dart';
import 'package:flutter_project_IJ/repo/post_network_repository.dart';
import 'package:flutter_project_IJ/widgets/my_progress_indicator.dart';
import 'package:flutter_tags/flutter_tags.dart';
import 'package:provider/provider.dart';
// TextEditingController를 위해 StatefulWidget로 변경
class SharePostScreen extends StatefulWidget {
final File imageFile;
final String postKey;
SharePostScreen(this.imageFile, {Key key, @required this.postKey})
: super(key: key);
@override
_SharePostScreenState createState() => _SharePostScreenState();
}
class _SharePostScreenState extends State<SharePostScreen> {
// 캡션 텍스트박스 컨트롤러
TextEditingController _textEditingController = TextEditingController();
List<String> _tagItems = [
"approval",
"pigeon",
"brown",
"expenditure",
"compromise",
"citizen",
"inspire",
"relieve",
"grave",
"incredible",
"voucher",
"girl",
"relax",
];
@override
void dispose() {
// 컨트롤러 종료
_textEditingController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Post'),
actions: [
TextButton(
onPressed: () async {
showModalBottomSheet(
context: context,
builder: (_) => MyProgressIndicator(),
isDismissible: false /* 닫을 수 없음 */,
enableDrag: false /* 드래그 불가 */,
);
// 이미지 업로드
await imageNetworkRepository.uploadImage(widget.imageFile,
postKey: widget.postKey);
UserModel usermodel =
Provider.of<UserModelState>(context, listen: false).userModel;
// 포스트 생성
await postNetworkRepository.createNewPost(
widget.postKey,
PostModel.getMapForeCreatePost(
userKey: usermodel.userKey,
username: usermodel.username,
caption: _textEditingController.text));
// 팝업 창을 닫음
Navigator.of(context).pop();
// share_post_screen을 닫음
Navigator.of(context).pop();
},
child: Text(
'Share',
textScaleFactor: 1.4,
style: TextStyle(color: Colors.blue),
),
)
],
),
body: ListView(
children: [
_captionWithImage(),
_divider,
_sectionButton('Tag People'),
_divider,
_sectionButton('Add Location'),
_tags(),
SizedBox(height: common_s_gap),
_divider,
SectionSwitch('Facebook'),
SectionSwitch('Instagram'),
SectionSwitch('Tumblr'),
_divider,
],
),
);
}
Tags _tags() {
return Tags(
horizontalScroll: true,
itemCount: _tagItems.length,
heightHorizontalScroll: 30 /* 높이 */,
itemBuilder: (index) => ItemTags(
index: index,
title: _tagItems[index],
activeColor: Colors.grey[200],
textActiveColor: Colors.black87,
borderRadius: BorderRadius.circular(4) /* 테두리 둥글기 */,
elevation: 2 /* 그림자 */,
splashColor: Colors.grey[800] /* 선택효과 색상 */,
color: Colors.red /* 선택 색상 */,
),
);
}
Divider get _divider => Divider(
color: Colors.grey[300],
height: 1,
thickness: 1,
);
ListTile _sectionButton(String title) {
return ListTile(
title: Text(
title,
style: TextStyle(fontWeight: FontWeight.w400),
),
trailing: Icon(Icons.navigate_next),
dense: true,
/* 작게 만듦. */
contentPadding: EdgeInsets.symmetric(horizontal: common_gap),
);
}
ListTile _captionWithImage() {
return ListTile(
contentPadding: EdgeInsets.symmetric(
vertical: common_gap,
horizontal: common_gap,
),
leading: Image.file(
widget.imageFile,
width: size.width / 6,
height: size.width / 6,
fit: BoxFit.cover,
),
title: TextField(
controller: _textEditingController,
autofocus: true,
decoration: InputDecoration(
hintText: 'Wirte a caption...',
border: InputBorder.none,
),
),
);
}
}
// 버튼에 변화를 줘야함 = StatefulWidget
class SectionSwitch extends StatefulWidget {
final String _title;
const SectionSwitch(
this._title, {
Key key,
}) : super(key: key);
@override
_SectionSwitchState createState() => _SectionSwitchState();
}
class _SectionSwitchState extends State<SectionSwitch> {
bool checked = false;
@override
Widget build(BuildContext context) {
return ListTile(
title: Text(
widget._title,
style: TextStyle(fontWeight: FontWeight.w400),
),
trailing: CupertinoSwitch(
value: checked,
onChanged: (onValue) {
setState(() {
checked = onValue;
});
},
),
dense: true,
/* 작게 만듦. */
contentPadding: EdgeInsets.symmetric(horizontal: common_gap),
);
}
}
'Flutter > Project_InstaClone(완)' 카테고리의 다른 글
[Flutter/Project](Instagram Clone) 본인을 제외한 모든 유저 가져오기 (0) | 2021.03.02 |
---|---|
[Flutter/Project](Instagram Clone) 포스트 이미지 다운로드 링크 저장 (0) | 2021.03.02 |
[Flutter/Project](Instagram Clone) 포스트 생성시 작성할 데이터 파일 post model (0) | 2021.02.27 |
[Flutter/Project](Instagram Clone) Firebase Storage Image Download (0) | 2021.02.25 |
[Flutter/Project](Instagram Clone) Firebase Storage Image Upload (0) | 2021.02.25 |
Comments