ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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
    
    

     

     

     

     

     

     

     

Designed by Tistory.