반응형
SMALL
FireBase
아주 빠르게 무언가를 시작할 수 있도록 도와줌(아이디어를 구상중일 때 많이 사용, 비즈니스 용으로는 많이 사용하지 않음)
Securing the Keys
- react app에서 환경변수를 설정하려면
REACT_APP_
으로 시작해야함 - key들을 .env에 저장
- <.env>에 저장하는 이유?
- <.gitignore> file에 .env를 작성한다면 .env에 쓴 키들은 git에 올라가지 않음 -> 보안상의 이유로 key,URL 들은 비공개
- 하지만 React application을 실행하면 서비스를 위해 빌드하고 웹사이트를 띄우면 create-react-app은 이 코드들을 실제 값들로 변환시켜 공개됨(단순히 github에 key를 업로드하지 않기 위함)
Router Setup
- Fragment (
<> </>
): 많은 요소들을 render하고 싶을 때 사용(부모 요소가 없을 때 )
Authentication
firebase.auth()
: Authentication 기능을 제공
Login
- onChange : 값이 바뀔때마다 사용
- argument인 event는 무슨 일이 일어났는지 확인해줌(target은 변경이 일어난 부분)
- input을 변경할 때마다 onchange function이 일어남 (input에서 value 받아옴)
- hooks를 이용해 상태 체크와 value 넣어주기 위해 사용
createUserWithEmailAndPassword
와signInWithEmailAndPassword
를 이용해 로그인- setPersistence : 사용자를 어떻게 기억할 것인지 선택하도록 도와줌
- default로 local
- local : 브라우저를 닫더라도 사용자 정보는 기억될 것이라는 의미
- session : 탭이 열려있는 동안에는 사용자 정보를 기억할 것이라는 의미
- none : 유저정보를 기억하지 않는 것
- onAuthStateChanged : (evnt listener) 유저 상태에 변화가 있을 때 변화를 알아차림
- signWithPopup : provider를 만들고 provider로 로그인
LogOut
const onLogOutClick=()=>authService.signOut();
: profile에서 logout 하는 기능 만들어줌- 로그아웃했을 때 "/"로 이동하는 두가지 방법
<Redirect from="*" to="/" />
을 통해 "/" 이외의 다른 루트일 경우 "/"로 가도록 설정 (in router.js)const history=useHistory(); history.push("/");
를 이용해 onLogiytClick 눌렀을 때 로그아웃 되도록 설정 (in Profile.js)
Form
const {taget:{value},}=event
==event.target.value
를 통해 input에서 받은 value를 set함
Database Set up
Cloud Firestore의 database는 NoSQL database
- collection (폴더와 같음) -> dociments의 그룹
- Document (컴퓨터에 있는 문서와 같은 텍스트)
- 하나의 database는 collection들을 가지고 있고 collection은 docment들을 가지고 있음
dbService.collection("nweets").add();
: "nweets"라는 collection에 document ID를 자동으로 부여하며 새로운 document 추가- firebase.js에 firestore을 dbservice로 export한 후 , home.js에서 import 해서 사용
const dbNweets=await dbService.collection("nweets").get();
: "nweets"라는 collection의 documnets get- dbNweets는 QueryDocumentSnapshot 형태이므로
dbNweets.forEach(document=> console.log(document.data()))
를 이용해야 document들 확인 가능
- dbNweets는 QueryDocumentSnapshot 형태이므로
setNweets([prev=>document.data(), ...prev]);
: set을 쓰는 함수에서 값 대신에 함수를 전달할 수 있음 -> 만약 함수를 전달하면 리액트는 이전 값에 접근할 수 있게 해줌dbNweets에 있는 모든 document에 대해 setNweets에서 함수를 사용하고 있는데 배열을 리턴, 이 배열에서 첫 번째 요소는 가장 최근 documet이고, 그 뒤로 이전 documet를 붙임
...
: spread attribute 기능 -> 데이터를 가져와서 풀어냄const [nweets,setNweets]=useState([]); const getNweets=async()=>{ const dbNweets=await dbService.collection("nweets").get(); dbNweets.forEach((document)=>{ //dbNweets에 있는 모든 document에 대해 setNweets에서 함수를 사용하고 있는데 배열을 리턴, 이 배열에서 첫 번째 요소는 가장 최근 documet이고, 그 뒤로 이전 documet를 붙임 const nweetObject={ ...document.data(),//...: spread attribute 기능 -> 데이터를 가져와서 풀어냄 id:document.id, }; setNweets(prev=>[nweetObject, ...prev]);//set을 쓰는 함수에서 값 대신에 함수를 전달할 수 있음 -> 만약 함수를 전달하면 리액트는 이전 값에 접근할 수 있게 해줌 }); /*dbNweets는 QueryDocumentSnapshot 형태이므로 dbNweets.forEach(document=> console.log(document.data()))를 이용해야 document들 확인 가능 */ }; useEffect(()=>{ getNweets(); },[]);
snapshot 이용
- getNweets로 documents를 얻는 방식은 오래된 방식이고 snapshot을 이용하면 편리
- snapshot은 실시간으로 전달됨
- 지우거나 업데이트 등 무언가를 하면 바로 실행되는 함수
useEffect(()=>{ dbService.collection("nweets").onSnapshot(snapshot=>{ const nweetArray=snapshot.docs.map(doc =>({id:doc.id, ...doc.data(),})); setNweets(nweetArray); }) },[]);
Delete and Edit
dbService.doc(
nweets/${nweetObj.id}).delete();
을 이용해서 nweets 삭제dbService.doc(
nweets/${nweetObj.id}).update({text:newNweet});
을 이용해서 text editstorageService.refFromURL(nweetObj.attachmentUrl).delete();
을 이용해 delete photo
Image
- FileReader API 이용
const onFileChange=(event)=>{ const {target:{files},}=event;//event가 target안의 files 가리킴 const theFile=files[0]; const reader=new FileReader(); reader.onloadend=(finishedEvent)=>{//event listner : 파일 로딩이 끝날 때 finishedEvent가짐 const {currentTarget:{result},}=finishedEvent; setAttachment(result) }; reader.readAsDataURL(theFile); }; const onClearAttachment =()=>setAttachment(null); //사진 clear시킴
Uploading
- reference: Google Cloud Storage object에 대한 참조를 나타냄
- child: 이 reference로부터 관련된 path로 reference를 반환
- uuid : 어떤 특별한 식별자를 랜덤으로 생성해줌
storageService.ref().child(
${userObj.uid}/${uuidv4()});
:파일에 대한 reference- 사진에 대한 아이디 생성해주기 위해 uuid 사용
Get My Nweets
const getMyNweets= async()=>{
const nweets=await dbService.collection("nweets").where("creatorId","==",userObj.uid).get(); //where은 필터링 하는 방법 표기
console.log(nweets.docs.map(doc=>doc.data()))
}
- where을 통해 필터링하는 기준을 만들어 creatorId와 userObj.id가 같은 경우에만 nweets에 들어가는 것을 알 수 있음
Update Profile
- profile을 변경해서 setUserObj를 하더라도 user은 방대한 양을 차지하므로 react에서 바로 rendering 안될 수도 있음
- 해결 방법
- userObj에서 이용하는 객체만을 전달해줌 (이 방법 선호)
setUserObj({//user를 저장해놓음 (user은 방대한 양을 차지하므로 이용하려는 객체들만 가져옴) displayName:user.displayName, uid:user.uid, updateProfile:(args)=>user.updateProfile(args), });
Object.assign({},user))
이용- 빈 object와 source 필요 -> 빈 object안에 source인 user의 사본이 새 object의 형태로 생성하여 react가 rendering됨
setUserObj(Object.assign({},user)));
- userObj에서 이용하는 객체만을 전달해줌 (이 방법 선호)
Deploying (배포)
- pacjage.json에
"homepage": "https://suminRoh.github.io/nwitter"
추가 - npm i gh-pages
- package.json의 scripts에
"predeploy":"npm run build","deploy":"gh-pages -d build"
추가 - npm run deploy
- homepage url로 들어가기
API Keys Security
반응형
LIST