---
# System prepended metadata

title: 릴레이프로젝트-33

---

# 릴레이프로젝트-33

firebase id : boostcamp202133@gmail.com
passwd : boostcamp2021

# 참가자

---

1주차

- [K056\_차지원](https://github.com/Cha-Ji)
- [J177\_장수용](https://github.com/waterdrag0n)
- [J016\_김기범](https://github.com/bumbum9944)
- [J063\_김필선](https://github.com/psunny0104)
- [S037\_이남준](https://github.com/ningpop)
- [J107\_송명회](https://github.com/mhsong95)
- [J187\_정요한](https://github.com/ingyeoking13)
- [S028\_오승민](https://github.com/sseungmn)

# 1주차: 기획

## 개발자의 집

---

### 기획의도

![https://user-images.githubusercontent.com/53979482/126754605-1bca911f-f211-44c1-98ab-502e45a5e51b.png](https://user-images.githubusercontent.com/53979482/126754605-1bca911f-f211-44c1-98ab-502e45a5e51b.png)

- 코로나가 장기화되면서, 재택근무가 보편화되고 있다. 주로, IT 업계를 중심으로 개발자들의 재택근무 환경 조성에 관심이 늘어나고 있으며, 책상의 개발 환경을 세팅하려는 개발자들의 수요가 있다.
- 다른 사람의 개발 환경을 통해 본인의 개발 환경을 개선하는데 도움을 받을 수 있으며, 같은 직종의 사람들에게 본인의 개발 환경을 공유하는 재미를 느낄 수 있다.
- 개발자의 환경 세팅은 물리적인 책상 세팅 뿐만 아니라 PC 내의 SW 개발 환경 세팅도 존재하므로 이 역시 활용 가능하다.

### 로고 구상

![https://noticon-static.tammolo.com/dgggcrkxq/image/upload/v1611156036/noticon/rdyjdhta27ylwjaob0eq.png](https://noticon-static.tammolo.com/dgggcrkxq/image/upload/v1611156036/noticon/rdyjdhta27ylwjaob0eq.png)

🔼 오늘의 집 로고

![https://user-images.githubusercontent.com/53979482/126754618-fbfbf78b-151d-4c82-a09d-1c3aff4fdb6c.png](https://user-images.githubusercontent.com/53979482/126754618-fbfbf78b-151d-4c82-a09d-1c3aff4fdb6c.png)

🔼 개발자의 집 임시 로고

---

### UI 구성

- 로그인 페이지
  - 계정을 등록하고 로그인을 할 수 있다. 이용자를 구분할 수 있는 기능이 필요하다.
- 메인 피드 페이지
  - 데스크 셋업에 대한 사진들을 볼 수 있는 타임라인 형식이다. 썸네일, 제목, 작성자가 간략하게 나타난다.
  - 마이페이지로 갈 수 있는 버튼이 존재한다.
  - 게시글 & 유저를 검색하하는 검색창이 존재한다.
- 게시글 상세 페이지
  - 확대한 사진과 좋아요 개수, 제목, 작성자 그리고 관련 제품 링크를 확인할 수 있다.
  - 게시물 스크랩, 좋아요
- 게시글 작성/수정 페이지
  - 게시글을 작성하고 사진에 제품 링크 포인트를 생성할 수 있다.
- 마이 페이지
  - 스크랩, 좋아요한 제품 & 게시글을 확인할 수 있는 페이지

**예시 링크**

[https://www.figma.com/embed?embed_host=notion&url=https%3A%2F%2Fwww.figma.com%2Fproto%2FCX3v3FVpvG0MeXfOOsLnps%2F%25EA%25B0%259C%25EB%25B0%259C%25EC%259E%2590%25EC%259D%2598-%25EC%25A7%2591-UI%3Fnode-id%3D0%253A1%26scaling%3Dscale-down%26starting-point-node-id%3D8%253A7441](https://www.figma.com/embed?embed_host=notion&url=https%3A%2F%2Fwww.figma.com%2Fproto%2FCX3v3FVpvG0MeXfOOsLnps%2F%25EA%25B0%259C%25EB%25B0%259C%25EC%259E%2590%25EC%259D%2598-%25EC%25A7%2591-UI%3Fnode-id%3D0%253A1%26scaling%3Dscale-down%26starting-point-node-id%3D8%253A7441)

---

### 기능구현

### A기능: 로그인 / 게시글 CRUD

- 로그인 기능
- 게시글 → 사진, 좋아요, 제품링크

### B기능: 태그/ 링크 / 카테고리

- 게시글 사진에 포함된 제품 링크 포인트(태그) 생성 (오늘의 집 예제 : [https://ohou.se/cards/3391646](https://ohou.se/cards/3391646) )

  링크는 제품 구매 정보와 연결되어 있음

  검색해도 없으면 직접 상품정보 간단하게 등록 가능

- 제품 → 가격 비교 사이트 검색 링크 or 쇼핑 관련 이용 (네이버 검색 API, 쿠팡, 다나와api 등), 카테고리 분류?

### C기능: 검색 / 마이페이지

- 게시글 + 유저 검색
- 마이페이지

### 2주차 : 로그인 / 게시글 CRUD

| 캠퍼 ID |  이름  |                         GitHub                         |
| :-----: | :----: | :----------------------------------------------------: |
|  J142   | 이민재 |          [jae464](https://github.com/jae464)           |
|  J174   | 임준혁 |         [jhLim97](https://github.com/jhLim97)          |
|  J039   | 김영진 |         [jin-Pro](https://github.com/jin-Pro)          |
|  S044   | 이정원 |   [devJungwonLee](https://github.com/devJungwonLee)    |
|  K014   | 김혜련 |          [hr0427](https://github.com/hr0427)           |
|  K054   | 정우진 |      [1600094806](https://github.com/1600094806)       |
|  J108   | 송연석 | [YeonSeok-Song](https://gist.github.com/YeonSeok-Song) |
|  J064   | 김하정 |    [Kim-Ha-Jeong](https://github.com/Kim-Ha-Jeong)     |

---

## 로그인

구글 로그인 API를 사용하여 해당 email을 불러와서 사용자를 식별 하였습니다.

```jsx
// 최초 API 설정
GoogleSignIn _googleSignIn = GoogleSignIn(scopes: ['email']);
```

```jsx
// 현재 로그인 상태 확인
GoogleSignInAccount? user = _googleSignIn.currentUser;
```

```jsx
// 로그인 안됐을 경우 함수 호출
await _googleSignIn.signIn();
```

![Screenshot_20210730-165225](https://user-images.githubusercontent.com/70205497/127639369-0b7ec037-6c73-45a5-86b4-907964ece8c4.jpg)

![Screenshot_20210730-192348_Google Play services](https://user-images.githubusercontent.com/70205497/127640411-871a1ff1-efff-4ff6-9b39-ec58ac2c049f.jpg)

## 게시글

###메인화면 구성

- 상단의 Appbar

  좌측의 로고와 앱 이름

  우측의 마이페이지, 업로드 버튼 (B, C 기능에서 구현)

- 검색창 TextField

  검색창을 터치하면 커서가 생기면서 키보드가 올라옴

  Focus된 상황에서 키보드 외부의 화면을 터치하면 키보드가 해제됨

  타이핑을 하여 Text가 생기면 우측에 Clear버튼이 생김.

  Clear버튼을 누르면 입력된 Text가 전부 지워짐.

  검색 기능은 이후 B, C에서 구현

- 중앙의 GridView

  서버로부터 로딩된 게시글들이 GridView를 통해 표시됨.

  하나의 게시글에는 썸네일 사진, 게시글 제목, 작성자로 이루어져있음

  GridView는 스크롤이 가능한 형태이며, 하나의 게시글을 터치하면 상세 화면 페이지로 넘어감.

![스크린샷 2021-07-30 오후 7 18 26](https://user-images.githubusercontent.com/70205497/127640407-0b30f946-6913-4378-905e-73bebf8dd369.png)

## Firebase

# Firebase 접근

![firebase설명 1](https://user-images.githubusercontent.com/70205497/127769940-909a7f62-c329-4add-ba21-34bb44be18e1.PNG)
![firebase설명 2](https://user-images.githubusercontent.com/70205497/127769959-0edd5414-bf15-4282-9022-d91fc6ba2ed5.PNG)
![firebase설명 3](https://user-images.githubusercontent.com/70205497/127769965-15bd6e07-37eb-4eb9-8a69-a8d3b1c4e144.PNG)
![firebase설명 4](https://user-images.githubusercontent.com/70205497/127769966-e8a732f0-42c1-44f0-93b3-74d712e7ba40.PNG)

```jsx
// 게시글 data
{
	"id":"작성자 아이디",
	"imageProd":{
		"link":"판매 주소",
		"name":"제품 이름",
		"price":가격,
		"sell":"판매처"
	},
	"imageSrc":"이미지 src",
	"nickname":"닉네임",
	"postNum":"게시글 번호",
	"title":"제목"
}
```

```jsx
// application 내부에서 게시글을 생성할때
// data들을 긁어와서 addfile내부에 data들을 넣어줘야하나
// application 내부에서 게시글 생성 기능을 구현하지 못함.
// Firebase DataBase에 저장할 데이터들을 위의 코드 형식을 참고하여
// addfile함수를 사용하면 Firebase에 저장이됩니다.

// Future<void> addfile(String inputSource, String email, String link, String name,
//     String title, int price, String sell, int postNum) async {
//   FirebaseStorage storage = FirebaseStorage.instance;
//   CollectionReference users = FirebaseFirestore.instance.collection('relay33');
//   final picker = ImagePicker();
//   PickedFile? pickedImage;
//   int Num = 0;
//   Num = await users.get().then((snap) => snap.size) + 1;
//   try {
//   pickedImage = await picker.getImage(
//   source:
//   inputSource == 'camera' ? ImageSource.camera : ImageSource.gallery,
//   maxWidth: 1920);
//
//   final String fileName = path.basename(pickedImage!.path);
//   File imageFile = File("pickedImage.path");
//
//   try {
//   // Uploading the selected image with some custom meta data
//   await storage.ref(fileName).putFile(imageFile,
//     SettableMetadata(customMetadata: {'postNum': Num.toString()}));
//   // Refresh the UI
//   } on FirebaseException catch (error) {
//   print(error);
//   }
//   } catch (err) {
//     print(err);
//   }
//
//   String fileTmp = path.basename(pickedImage!.path);
//
//   String download = await storage.ref(fileTmp).getDownloadURL();
//
//   final Map<String, Object> data = {
//   'id': email,
//   'title': title,
//   'imageProd': {'link': link, 'name': name, 'price': price, 'sell': sell},
//   'imageSrc': download,
//   'postNum': Num
//   };
//
//   users
//       .doc(Num.toString())
//       .set(data)
//       .then((value) => print("User added"))
//       .catchError((err) => print(err));
// }
```

```jsx
// data 가져오기
    Future<List<Map<String, dynamic>>> getfile() async {
  FirebaseStorage storage = FirebaseStorage.instance;

  List<Map<String, dynamic>> files = [];

	//collection 연결
  CollectionReference users = FirebaseFirestore.instance.collection('relay33');

  final ListResult result = await storage.ref().list();
  final List<Reference> allFiles = result.items;

  // return allFiles;
  await Future.forEach<Reference>(allFiles, (file) async {
  final String fileUrl = await file.getDownloadURL();
  final FullMetadata fileMeta = await file.getMetadata();
  // print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
  // print(fileMeta.customMetadata?['postNum']);
  final info = await users
      .doc(fileMeta.customMetadata?['postNum'])
      .get()
      .then((DocumentSnapshot ds) {
  return ds.data();
  });

  files.add({
  "url": fileUrl,
  "path": file.fullPath,
  "info" : info,
  //info안에 데이터들을 나눠서 가져오려 했으나
  //잘처리가 되지 않아서 info를 갖고와서 사용할떄 분해함
  //"title": info['title'],
  });
  });
  //print(files);
  return files;
}
```

저희는 로그인 기능은 Google API를 사용하여 구현을 했으며
포스트 관련 기능 CRUD 기능을 Firebase를 사용하여 구현을 하였습니다.

하지만, CRUD기능

- Creat

  => Firebase에 Data를 add해주는 함수는 구현하였습니다.
  => UI 에서 Data를 긁어오는 기능이 구현이 되어있지 않습니다.
  => 따라서, 게시글 쓰기 버튼을 통해 Data를 Create는 불가능하며
  => 임의로 코드 내부에서 DummyData를 생성하여 Create는 가능합니다.

- Read

  => getfile을 통하여 Firebase에 존재하는 데이터 와 이미지를 가져옵니다.
  => 가져온 data를 기반하여 UI를 렌더링해줍니다.

- Update

  => 게시글에 대하여 수정하기 구현이 되어 있지 않습니다.
  => Create 기능이 구현된다면, Update는 빠르게 진행될 거라 생각합니다.

- Delete

  => 게시글에 대하여 삭제 기능이 구현이 되어 있지 않습니다.
  => target Post에 대하여 postNum을 firebase에 넘겨주어
  => 해당하는 postNum에 대한 data를 삭제 해주고 리렌더링합니다.

  <br>

### 3주차 : 태그 / 링크 / 카테고리

팀원: [S006 김민서](https://github.com/mingso), K020*박병준, J030*김병윤, J038*김영수, J052*김정윤, J124*염진호, J153*이유찬, J164\_이찬호

# 업데이트 사항

1. 데이터베이스 데이터 추가

   어플에서 사용자의 입력을 받아 db로 넘기는 부분이 존재하지 않습니다.

   따라서 어플에서 받는 입력의 형식을 바꾸는 방식이 아닌, db의 데이터 자체를 수작업으로 업데이트 하는 과정을 통해서 필요한 데이터를 추가하였습니다. (파이어베이스 직접 데이터 삽입)

   ![Untitled](https://user-images.githubusercontent.com/48426909/128479578-0158a827-6273-4250-981e-19ca5c0ddb24.png)

   아래의 설명은 firestore database를 간단하게 설명해 놓은 것입니다.

   : Firestore Database 클릭 → relay33 컬렉션 선택 → 원하는 문서 선택 → taglist → 원하는 제품 선택 → imageURL, url, name 데이터 저장.

   ![Untitled 1](https://user-images.githubusercontent.com/48426909/128479556-773cba79-fb2e-44e9-83ea-56b44eeadcfa.png)

   - url: 해당 제품의 구매 링크
   - imageURL: 해당 제품의 사진
   - name: 해당 제품의 이름

   어플에서 사용자의 입력을 받아 db로 넘기는 부분이 존재하지 않는다는 사실을 인지하고, 4주차 기능 구현을 하시길 바랍니다.

2. 업로드 이미지와 관련 있는 제품의 구매 링크 표기

   아래의 이미지를 확인하면, 업로드 이미지와 관련이 되어 있는 제품들 구매 링크가 있는 것을 확인할 수 있습니다.

- 기획 요구 사항

  ![Untitled 2](https://user-images.githubusercontent.com/48426909/128479569-9adc42d0-c31c-4b0a-aba4-2491aebb8eee.png)

- 구현 사항

  ![image](https://user-images.githubusercontent.com/48426909/128478972-d8308836-e58a-4fa6-9183-d9ed999ae67a.png)!

- 기획 요구사항에서 태그 목록을 파이어베이스에서 불러오는 기능만 수행하였습니다. 일단 태그의 이미지와, 태그의 이름(제품 이름)만 표시하게 구현하였습니다.
- 제품의 이름과 구매 링크, 이미지의 경우 사람이 입력을 하였습니다.
- 게시물을 만드는 과정 속에서 제품의 이름을 명시할 수 있다면, 이를 통해서 크롤링 하여 데이터를 받아오는 것도 충분히 고려해볼만한 사항입니다.
- 하지만 create 기능에서 이를 추가하는 것이 불가하다고 생각하여, 구현하지 못하였습니다.
- 네이버 쇼핑 API를 사용하는 것도 한 방법일 것입니다. 인증키를 발급해두었으니 사용하면 될 것 같습니다.

  Client ID : M5_DqGAGPPeaWTCJbOJc

  Client Secret : pwv_rGYEHB

-

# 주의 사항

1. **CRUD에서 추가로 구현해야할 점**

   - Create 기능

     - 앱을 실행한 상태에서 DB로 접근할 수 없습니다.

     - addfile 함수를 사용해서 앱을 실행하여, dummy 데이터를 넣는 방법이 유일한 접근 방법입니다.

     - firebase 어플 등록을 안드로이드만 되어 있어 ios를 사용할 수 없습니다.

   - Read 기능

     - 메인페이지 카드들의 정보를 읽어오는 기능이 구현되어 있지 않습니다.(파이어베이스에는 저장이 되어있습니다.)

     - 메인페이지에서 각각의 카드를 클릭하면, 디테일 페이지로 넘어가며 그 디테일 페이지의 태그 정보는 출력되게 구현했습니다.

   - Update 기능

     **구현 안됨**

   - Delete 기능

     **구현 안됨**

2. 비정상적인 동작
   - 안드로이드에서 구글 로그인이 진행되지 않습니다.(구글 인증 부분 다시 구현이 필요합니다.)
   - iOS에서 설치 및 작동이 되지 않습니다.




# 4주차 (08.13)

| 캠퍼 ID |  이름  |                         GitHub                         |
| :-----: | :----: | :----------------------------------------------------: |
|  J017   | 김기한 |          [vgihan](https://github.com/vgihan)           |
|  J023   | 김무성 |         [ddb8036631](https://github.com/ddb8036631)    |
|  J028   | 김민주 |         [deli-ght](https://github.com/deli-ght)        |
|  J120   | 안승재 |   [getState](https://github.com/getState)              |
|  J166   | 이충헌 |          [lodado](https://github.com/lodado)           |
|  K051   | 장성희 |      [ddanglehee](https://github.com/ddanglehee)       |
|  S014   | 김태훈 | [KTH-INHA-16](https://gist.github.com/KTH-INHA-16)     |
|  S039   | 이수현 |    [soohyeon0487](https://github.com/soohyeon0487)     |

---


## 릴레이 프로젝트 기능 현황

### 로그인 기능 (A)
- Social Login으로 구현 (google) -> 현재 로그인 안됨
- Auth Token을 처리하지 못함.

### 게시글 기능 (A)
- 생성
    - Firebase에서 직접 추가해야만 가능
    - 생성을 위한 별도 뷰는 존재하지 않으나 데이터를 넣어서 Firebase에 추가는 가능
- 조회
    - Firebase의 자료를 가져와 UI에 반영
- 수정
    - 기능 구현 없음
- 삭제
    - 기능 구현 없음

### 게시글 추가 정보 제공 기능 (B)
- 태그
    - 데스크 사진에 포함된 기기들에 대한 태그 조회
    - 추가 수정 삭제 없음
- 링크
    - 기능 구현 없음
- 카테고리
    - 기능 구현 없음

### 게시글 검색과 마이페이지 기능 (C)

- 검색
    - Firebase의 CRUD 기능과 토큰 처리가 이루어지지 않아 구현 불가
- 마이페이지
    - Firebase에 유저 정보 자체가 존재하지 않았고 기존의 Google 소셜 로그인 또한 정상적으로 진행이 불가


## 릴레이프로젝트 소감💐

### J017 김기한
- 피어세션 팀원들과는 서로 도와주고 격려하는 분위기 였다면, 릴레이 프로젝트 팀원과는 일주일간의 피로를 웃음으로 풀고 편안한 마음으로 개발을 진행할 수 있어 유쾌했습니다. 또한 깃 활용에 있어서 습득한 부분이 매우 큽니다. 혼자서 깃 이론을 공부할 때는 언제 해당 명령어를 사용해야하는지 모르고 외우기만 했다면, 릴레이프로젝트를 진행하면서 팀원분들이 사용하는 것을 직접 보기도 하고, 본 것을 적용해보기도 하며 많은 것을 얻어가는 것 같습니다. 4주차 팀원 비록 짧은 시간이었지만 엄청 유쾌한 분들이었네요! 수고 많으셨습니다!
### J023 김무성
- 기본 지식 하나 없이 플러터라는 기술 스택을 사용하면서 어려움을 많이 느꼈던 것 같습니다.
- 모바일 애플리케이션 프로젝트를 처음 접했는데, 모바일 스택 캠퍼분들의 많은 도움을 받았습니다.
- 다른 사람이 진행한 기획과 개발을 이어 받아 진행한다는 점이 새로웠습니다.
### J028 김민주
- 짧은 시간이었지만 프로젝트를 경험 할 수 있어 보람찬 시간이었습니다. 처음 접하는 언어로 무언가를 만들어고 심지어 다른 사람이 짠 코드를 이어받아 짜는게 쉽진 않았지만 좋은 분들과 함께 협업해 잘 풀어나갈 수 있었습니다. 다들 4주간 수고 많으셨어요~! 
### J120 안승재
- 마지막 한주 까지 무사히? 끝난 것 같아서 다행입니다. 언제든지 다른 사람이 내 코드를 볼 수도 있고, 수정할 수도 있다는 생각을 가지고 코딩을 해야겠다는 생각이 들었습니다. 모두 수고하셨어요!! 
### J166 이충헌
- 4주간 처음 배워보는 기술들을 써보면서 많이 성장한거 같습니다. 모두 수고하셨고 잘되시길 바랍니다!
### K051 장성희
- 플러터에 대한 지식 없이 다 같은 상황에서 언어 공부부터 시작하는 프로젝트는 처음이자 마지막이 아닐까 싶습니다. 그 속에서 서로 도와주면서 함께 어플리케이션을 만들어낸다는 게 재미있었습니다. 그동안 모두들 수고하셨습니다!
### S014 김태훈
- 무야호
### S039 이수현
- EOF \r\n\r\n






