firebase.js
import { initializeApp } from "firebase/app";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
};
const app = initializeApp(firebaseConfig);
export const storage = getStorage(app);
export const db = getFirestore();
App.jsx
import React from 'react';
import Upload from './Upload';
const App = () => {
return (
<React.Fragment>
<Upload />
</React.Fragment>
);
}
export default App;
userConst.js
import { serverTimestamp } from 'firebase/firestore';
const user = Object.freeze({
id: '',
urlList: [],
createdAt: serverTimestamp()
});
export { user };
Image.jsx
import React from 'react';
const Image = (props) => {
return (
<React.Fragment>
<img src={props.url} alt={props.name} />
</React.Fragment>
);
}
export default Image;
Upload.jsx
import React, { useState, useEffect } from 'react';
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
import { collection, addDoc, getDocs, updateDoc, query, orderBy } from 'firebase/firestore';
import { storage, db } from '../scripts/firebase';
import { user } from '../scripts/userConst';
import Image from './Image';
const maxImageCount = 5;
const getDataURL = (file) => {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => {
const dataURL = reader.result;
resolve(dataURL);
}
reader.readAsDataURL(file);
});
}
const Upload = () => {
const [files, setFiles] = useState([]);
const [images, setImages] = useState([]);
const [posted, setPosted] = useState([]);
const handleInputChange = async (event) => {
const fileList = Array.from(event.target.files);
const imageList = [];
for (const file of fileList) {
const dataURL = await getDataURL(file);
imageList.push(
<Image key={file.name} url={dataURL} name={file.name} />
);
}
setFiles(fileList);
setImages(imageList);
}
const handleSubmit = async (event) => {
event.preventDefault();
const usersRef = collection(db, 'users');
const userDocRef = await addDoc(usersRef, user);
const urlList = await Promise.all(files.map(async (file) => {
const storageRef = ref(storage, `images/${userDocRef.id}/${file.name}`);
await uploadBytes(storageRef, file).then(() => {
console.log('Uploaded!');
});
const url = await getDownloadURL(storageRef);
return url;
}));
await updateDoc(userDocRef, {id: userDocRef.id, urlList});
}
const getPostedImages = async () => {
const usersRef = collection(db, 'users');
const q = query(usersRef, orderBy('createdAt', 'desc'));
const querySnap = await getDocs(q);
const postedList = [];
let count = 0;
for (const doc of querySnap.docs) {
const urlList = doc.data().urlList;
for (const url of urlList) {
const name = url.split('?')[0].split('%2F').slice(-1)[0];
postedList.push(
<Image key={url} url={url} name={name} />
);
count++;
if (count >= maxImageCount) {
setPosted(postedList);
return;
}
}
}
setPosted(postedList);
}
useEffect(() => {
getPostedImages();
}, []);
return (
<React.Fragment>
<form>
<input
type='file'
accept='image/*'
multiple
onChange={handleInputChange}
/>
<button type='submit' onClick={handleSubmit}>送信</button>
</form>
{ images }
<p>----------------------------------------------------------------------------------------------------</p>
{ posted }
</React.Fragment>
);
}
export default Upload;
参考
Cloud Firestore にデータを追加する | Firebase