-
Instagram 클론 -3) backend와 frontend 합치기Spring 2021. 6. 12. 00:30
먼저 sign in, up 페이지를 합치자
먼저 firebase로 가서 authentification을 시작한다.
이번에는 firebase documentation으로 가서 웹시작하기를 눌러준다.
빌드> 인증>비밀번호로 인증하기를 들어간다.
이제 우리 프로젝트에 firebase를 넣자.
다음의 문서를 참고해서 순서대로 진행한다.
frontend에
npm install --save firebase
이후 components에 firebase.js파일을 만들어주자.
import firebase from "firebase/app"; var firebaseConfig = { apiKey: "AIzaSyDOCAbC123dEf456GhI789jKl01-MnO", authDomain: "myapp-project-123.firebaseapp.com", databaseURL: "https://myapp-project-123.firebaseio.com", projectId: "myapp-project-123", storageBucket: "myapp-project-123.appspot.com", messagingSenderId: "65211879809", appId: "1:65211879909:web:3ae38ef1cdcb2e01fe5f0c", measurementId: "G-8GSGZQ44ST" }; firebase.initializeApp(firebaseConfig);
이제 auth도 기능하도록 추가한다.
import firebase from "firebase/app"; var firebaseConfig = { apiKey: "AIzaSyDOCAbC123dEf456GhI789jKl01-MnO", authDomain: "myapp-project-123.firebaseapp.com", databaseURL: "https://myapp-project-123.firebaseio.com", projectId: "myapp-project-123", storageBucket: "myapp-project-123.appspot.com", messagingSenderId: "65211879809", appId: "1:65211879909:web:3ae38ef1cdcb2e01fe5f0c", measurementId: "G-8GSGZQ44ST" }; firebase.initializeApp(firebaseConfig); const auth = firebase.auth(); const storage = firebase.storage(); export {storage, auth};
이제 firebase로 가서 스토어리지 시작하기를 눌러주고 설정을 해준다.
이후 파이어베이스에가서 web버튼을 눌러서 웹을 시작해준다.
생성된 sdk를 이제 추가해줄 것이다.
(프로젝트 설정에서 키를 확인할 수 있다)
import firebase from "firebase/app"; var firebaseConfig = { apiKey: "AIzaSyCA3K2h0ruFbm5uGSSKy7phlfciwyDk44s", authDomain: "instaclone-81390.firebaseapp.com", projectId: "instaclone-81390", storageBucket: "instaclone-81390.appspot.com", messagingSenderId: "132017038415", appId: "1:132017038415:web:5273f00004d375b496b63a", measurementId: "G-DC46XH78GV" }; firebase.initializeApp(firebaseConfig); const auth = firebase.auth(); const storage = firebase.storage(); export {storage, auth};
이제 signup컴포넌트로 가서 인증을 설정해주자.
import React, { useState } from 'react' import '../LoginPage/LoginPage.css' import {storage, auth} from '../firebase' function Signup() { const [emailId, setEmailId] = useState(""); const [name, setName] = useState(""); const [userName, setUserName] = useState(""); const [password, setPassword] = useState(""); const newSignUp=()=>{ auth.createUserWithEmailAndPassword(emailId, password) .then((userCredential) => { // Signed in var user = userCredential.user; // ... }) .catch((error) => { var errorCode = error.code; var errorMessage = error.message; // .. }); } return ( <div> <input className="loginpage__text" value = {emailId} required onChange={e=> setEmailId(e.currentTarget.value)} type="text" placeholder="Mobile number or email" /> <input className="loginpage__text" value = {name} required onChange={e=>setName(e.currentTarget.value)} type="text" placeholder="Full Name" /> <input className="loginpage__text" value = {userName} required onChange={e=>setUserName(e.currentTarget.value)} type="text" placeholder="Username" /> <input className="loginpage__text" value={password} required onChange={e=>setPassword(e.currentTarget.value)} type="password" placeholder="Password" /> <button className="loginpage__button" onClick={newSignUp} >Sign up</button> </div> ) } export default Signup
signin도 적용하자.
import React, { useState } from 'react' import '../LoginPage/LoginPage.css' import {storage, auth} from '../firebase'; function Signin() { const [emailId, setEmailId] = useState("") const [password, setPassword] = useState("") const login=() =>{ auth.signInWithEmailAndPassword(emailId, password) .then((userCredential) => { // Signed in var user = userCredential.user; localStorage.setItem("users", user); window.location.reload(); }) .catch((error) => { var errorCode = error.code; var errorMessage = error.message; }); } return ( <div> <input className="loginpage__text" value={emailId} onChange={e=> setEmailId(e.currentTarget.value)} type="text" placeholder="Phone number, username, or email" /> <input className="loginpage__text" value = {password} onChange={e=>setPassword(e.currentTarget.value)} type="password" placeholder="Password" /> <button className="loginpage__button" onClick={login} >Log In</button> </div> ) } export default Signin
이제 메인 페이지에서 사진을 선택해서 post 하는 기능을 만들자 .
import React, { useEffect, useState } from 'react' import Post from '../Post/Post' import './MainPage.css' import uploadImage from '../../images/upload1.png' function MainPage() { const [postArray, setPostArray] = useState([]) useEffect(() => { getPost(); }, []) const getPost = () =>{ let data=[ { "postId" : "12333", "userprofile":"https://cdn.dnaindia.com/sites/default/files/styles/full/public/2020/12/25/945556-two-penguins-comforting-each-other-viral-picture.jpg", "userName": "user234", "postImageURL" : "https://www.shutterstock.com/blog/wp-content/uploads/sites/5/2019/07/Man-Silhouette.jpg", "timeStamp":"20210214", "likes":"13" }, { "postId" : "2344", "userprofile":"https://cdn.dnaindia.com/sites/default/files/styles/full/public/2020/12/25/945556-two-penguins-comforting-each-other-viral-picture.jpg", "userName": "user2244", "postImageURL" : "https://www.shutterstock.com/blog/wp-content/uploads/sites/5/2019/07/Man-Silhouette.jpg", "timeStamp":"20210214", "likes":"1543" } ] setPostArray(data); } return ( <div> <div style={{"textAlign":"center", "margin":"10px"}} className="mainpage__container"> <div className="mainpage__divider"></div> <div className="fileupload"> <label htmlFor="file-upload"> <img className="mainpage__uploadicon" src={uploadImage} alt="" /> </label> <input id = "file-upload" type="file" /> </div> <div className="mainpage__divider"></div> </div> { postArray.map(item=>( <Post profile={item.userprofile} id={item.postId} username={item.userName} postImage={item.postImageURL} likes={item.likes}/> )) } </div> ) } export default MainPage
css
.mainpage__uploadicon{ height: 60px; width: 50px; } .mainpage__divider{ height: 8px; width: 22px; border: 1px solid #dbdbdb; margin-top: 40px; } .mainpage__container{ text-align: center; margin: 0px 10px 0px -20px; display: flex; justify-content: center; } .fileupload >input{ display: none; }
이제 파일 업로드하는firebase를 이용하자.
import React, { useEffect, useState } from 'react' import Post from '../Post/Post' import './MainPage.css' import uploadImage from '../../images/upload1.png' import { storage } from '../firebase' function MainPage() { const [postArray, setPostArray] = useState([]) const [progressBar, setProgressBar] = useState("") useEffect(() => { getPost(); }, []) const getPost = () =>{ // let data=[ // { // "postId" : "12333", // "userprofile":"https://cdn.dnaindia.com/sites/default/files/styles/full/public/2020/12/25/945556-two-penguins-comforting-each-other-viral-picture.jpg", // "userName": "user234", // "postImageURL" : "https://www.shutterstock.com/blog/wp-content/uploads/sites/5/2019/07/Man-Silhouette.jpg", // "timeStamp":"20210214", // "likes":"13" // }, // { // "postId" : "2344", // "userprofile":"https://cdn.dnaindia.com/sites/default/files/styles/full/public/2020/12/25/945556-two-penguins-comforting-each-other-viral-picture.jpg", // "userName": "user2244", // "postImageURL" : "https://www.shutterstock.com/blog/wp-content/uploads/sites/5/2019/07/Man-Silhouette.jpg", // "timeStamp":"20210214", // "likes":"1543" // } // ] fetch("localhost:8080/post") .then(response=> response.json()) .then(data =>{ setPostArray(data); }) } const upload = (event) =>{ let image = event.target.files[0]; if(image ===null || image===undefined){ return ; } var uploadTask = storage.ref("images").child(image.name).put(image); uploadTask.on( 'state_changed', function(snapshot){ var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; setProgressBar(progress); }, function(error) { }, function() { uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) { console.log('File available at', downloadURL); let payload = { "postId" : Math.floor(Math.random()*100000), "userId": JSON.parse(localStorage.getItem("users")).uid, "postPath" : downloadURL, "timeStamp": new Date().getTime(), "likeCount" : 0 } const requestOptions = { method:"POST", headers:{ "ContentType" : "application/json"}, body: JSON.stringify(payload) } fetch("localhost:8080/post", requestOptions) .then(response=> response.json()) .then(data =>{ console.log(data) getPost(); }) .catch(error=>{ }) }); }); } return ( <div> <div style={{"textAlign":"center", "margin":"10px"}} className="mainpage__container"> <div className="mainpage__divider"></div> <div className="fileupload"> <label htmlFor="file-upload"> <img className="mainpage__uploadicon" src={uploadImage} alt="" /> </label> <input onChange={upload} id = "file-upload" type="file" /> </div> <div className="mainpage__divider"></div> </div> <div className="upload_text">{progressBar}%</div> { postArray.map(item=>( <Post profile={item.userprofile} id={item.postId} username={item.userName} postImage={item.postPath} likes={item.likeCount}/> )) } </div> ) } export default MainPage
추가로 백엔드에서 파일이 업로드 될 때,
최근것이 먼저 오도록 다음과 같이 postService를 수정해준다.
package com.yunhalee.Instagram_App.Service; import java.util.ArrayList; import java.util.Collections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.yunhalee.Instagram_App.Entity.Post; import com.yunhalee.Instagram_App.Repository.PostRepository; @Service public class PostService { @Autowired UserService userService; @Autowired PostRepository postRepository; public Post submitPostToDatabase(Post post) { return postRepository.save(post); } public ArrayList<Post> retrivePostFromDB(){ ArrayList<Post> postList = postRepository.findAll(); for(int i=0;i<postList.size();i++) { Post postItem=postList.get(i); postItem.setUserName(userService.displayUserMetaData(postItem.getUserId()).getUserName()); } Collections.sort(postList, (a,b)-> b.getId() - a.getId()); return postList; } }
이제 comment를 정리하자.
post.js
import { Avatar } from '@material-ui/core' import React, { useEffect, useState } from 'react' import './Post.css' import postImage from '../../images/post.jpg' import love from '../../images/love.svg' import comment from '../../images/comment.svg' import share from '../../images/share.svg' function Post(props) { const [commentList, setCommentList] = useState([]) useEffect(() => { getComment(); }, []) const getComment= () =>{ // let data = [ // { // "username":"user1", // "commnetId" : "user123 ", // "timeStamp" : "20210101", // "description":"wow" // }, // { // "username":"user1", // "commnetId" : "user123 ", // "timeStamp" : "20210101", // "description":"wow" // }, // { // "username":"user1", // "commnetId" : "user123 ", // "timeStamp" : "20210101", // "description":"wow" // } // ] fetch("localhost:8080/comments" + this.props.id) .then(response=> response.json()) .then(data =>{ setCommentList(data); }) } const submitComments= (e) =>{ if(e.key ==="Enter") { let comment = e.currentTarget.value; if(comment !==null || comment !== undefined){ let payload = { "commentId" : Math.floor(Math.random()*100000).toString(), "userId" : JSON.parse(localStorage.getItem("users")).uid, "postId" : props.id, "timeStamp": new Date().getTime(), "comment" : comment } const requestOptions = { method:"POST", headers:{ "ContentType" : "application/json"}, body: JSON.stringify(payload) } fetch("localhost:8080/comments", requestOptions) .then(response=> response.json()) .then(data =>{ getComment(); }) .catch(error=>{ }) } } } return ( <div className="post__container"> {/* Header */} <div className="post__header"> <Avatar className="post__image" src={props.profile}/> <div className="post__username">{props.username}</div> </div> {/* Image */} <div className="post__img"> <img src={props.postImage} alt="" width="615px" /> </div> {/* Analytics */} <div className="post__analytics"> <div style={{"marginLeft":"10px"}}> <img src={love} className="post__reactImage" alt="" /> <img src={comment} className="post__reactImage" alt="" /> <img src={share} className="post__reactImage" alt="" /> </div> <div style={{"fontWeight":"bold", "marginLeft" :"20px"}} >{props.likes} likes</div> </div> {/* Comment Section */} <div> { commentList.map((item)=>( <div className="post__comment"> {item.username} : {item.comment}</div> )) } <input className = "post__commentBox" onKeyPress={submitComments} type="text" placeholder="Add a comment ... " /> </div> </div> ) } export default Post
'Spring' 카테고리의 다른 글
JSP : Standard JSP Tag Library (JSTL) - Core Tags (0) 2021.06.18 JSP : 사용자 action을 session, cookie에 따라서 추적하기 (To Do, 쿠키 사이트) (0) 2021.06.18 JSP의 기본 사용 방법 (0) 2021.06.18 Instagram 클론 -2) status, post, comment모델 만들기 (0) 2021.06.12 Instagram 클론 -1) springboot시작하고 user모델 만들기 (0) 2021.06.11