React+Next.js+firebaseで画像アップローダを作った
このサイト参考にアップロードサイト作成中
How to do image upload with firebase in react.
ただ、firebaseの認証等は、「react.js&next.js超入門 第2版」を参考に、
components/fire.js
に保存
//App.js // このサイト参考にアップロードサイト作成中 // https://dev.to/itnext/how-to-do-image-upload-with-firebase-in-react-cpj // いったん開発の間はstorageのルールの認証を切る // いちいちログインするの時間がかかり非効率 // firebase公式ドキュメントも参考にする // https://firebase.google.com/docs/storage/web/start?hl=ja //またreact.js&next.js超入門 第2版も参考にした //https://www.shuwasystem.co.jp/book/9784798063980.html import { useState } from "react" import firebase from "firebase" import Layout from "../../components/layout" import "../../components/fire" const auth = firebase.auth(); const provider = new firebase.auth.GoogleAuthProvider(); const storage= firebase.storage() auth.signOut() export default function Index() { const [user,setUser]=useState(null); const [message, setMessage] = useState('please login ...'); // ログイン処理 const login = () =>{ console.log("login") auth.signInWithPopup(provider).then( result=>{ setUser(result.user.displayName); setMessage('logined: '+result.user.displayName); }, error=>{ setUser('NONE'); setMessage('not logined.') } ) } // ログアウト処理 const logout = () => { auth.signOut(); setUser(null); setMessage('logout...') } // ログイン表示をクリックしたとき const doLogin = (e) => { if (auth.currentUser == null){ login(); } else { logout(); } } return ( <div> <Layout header="Next.js" title="Top page."> <div className="alert alert-primary text-center"> <h6 className="text-right" onClick={doLogin}>LOGINED: {user}</h6> <h5 className="mb-4">{message}</h5> </div> <Upload /> </Layout> </div> ) } function Upload() { console.log("Upload 呼び出し") const allInputs = {imgUrl: ''} const [imageAsFile, setImageAsFile] = useState('') const [imageAsUrl, setImageAsUrl] = useState(allInputs) console.log(imageAsUrl) const handleImageAsFile = (e) => { const image = e.target.files[0] setImageAsFile(imageFile => (image)) } const handleFireBaseUpload = e => { e.preventDefault() console.log('start of upload') // async magic goes here... if(imageAsFile === '' || imageAsFile === undefined) { console.error(`not an image, the image file is a ${typeof(imageAsFile)}`) } else { const uploadTask = storage.ref(`/images/${imageAsFile.name}`).put(imageAsFile) //initiates the firebase side uploading //https://firebase.google.com/docs/storage/web/upload-files?hl=ja#monitor_upload_progress //このドキュメントだけ呼んだだけだと分かりにくいが、 //uploadTask.onの第1引数に'state_changed'を指定すると //第2、第3、第4引数に渡した関数で // アップロード状況を管理することができる。 uploadTask.on('state_changed', (snapShot) => { //takes a snap shot of the process as it is happening console.log(snapShot) }, (err) => { //catches the errors console.log(err) }, () => { // gets the functions from storage refences the image storage in firebase by the children // gets the download url then sets the image from firebase as the value for the imgUrl key: storage.ref('images').child(imageAsFile.name).getDownloadURL() .then(fireBaseUrl => { //オブジェクトのスプレッド構文による展開と、値の更新 //{imgUrl: 古いURL}を{imgUrl: 新しいURL}に更新している。 //https://qiita.com/FumioNonaka/items/58358a29850afd7a0f37 setImageAsUrl(prevObject => ({...prevObject, imgUrl: fireBaseUrl})) }) }) } } return <div> <form className="form-group" onSubmit={handleFireBaseUpload}> <input className="form-control-file mb-1" // allows you to reach into your file directory and upload image to the browser type="file" onChange={handleImageAsFile} /> <button className="btn btn-primary">アップロード</button> </form> <img src={imageAsUrl.imgUrl} alt="image tag" /> </div> }