# Firebase Storage
Date: 20200707
api: https://firebase.google.com/docs/storage/web/start
教學影片: https://www.youtube.com/watch?v=SpxHVrpfGgU
參考檔案: https://gist.github.com/sawaYch/f538d10d09ccf84cbff07e93a0b6cd0d
六角學院 士堯大大 https://hackmd.io/@vcJEpSOaRoy7aT_3oIqfvg/HJVtyyBSr
[TOC]

儲存的空間位置
gs://tvbox-7ebb7.appspot.com/track/video_text_tracks.vtt
下載網址:
https://storage.cloud.google.com/tvbox-7ebb7.appspot.com/track/video_text_tracks.vtt
### [0] 開始前,先修改 Rule 開啟權限
```yam=
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
```
修改第五行 `if true` 開啟權限,才能上傳檔案
```yam=
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}
```
### [1] 上傳檔案
```html
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-storage.js"></script>
<progress value="0" max="100" id="uploader">0%</progress></br>
<input type="file" value="upload" id="uploadBtn"></br>
<div id="msg"></div>
```
```jsx
var config = {
apiKey: "xxx",
authDomain: "xxx-6be2f.firebaseapp.com",
databaseURL: "https://xxx-6be2f.firebaseio.com",
projectId: "xxx-6be2f",
storageBucket: "xxx-6be2f.appspot.com",
messagingSenderId: "271709208420",
appId: "xxx",
};
firebase.initializeApp(config);
const uploader = document.getElementById("uploader");
const uploadBtn = document.getElementById("uploadBtn");
const msg = document.getElementById("msg");
uploadBtn.addEventListener("change", (event) => {
// Get file
const file = event.target.files[0];
// Create a storage ref
const storageRef = firebase.storage().ref("sweet_gifts/" + file.name);
// Upload file
var task = storageRef.put(file);
// Upload Progress bar
task.on(
"state_changed",
function progress(snapshot) {
console.log(snapshot);
},
function error(err) {},
function complete() {}
);
});
```
### [2] 查看檔案列表
Origin
```jsx
var listRef = firebase.storage().ref('sweet_gifts/')
// Find all the prefixes and items.
listRef.listAll().then(function(result) {
result.items.forEach(function(ref) {
ref.getDownloadURL().then(function(url){
console.log(ref.name) // 檔案名稱
console.log(url) // 檔案網址
});
});
}).catch(function(error) {
console.log(error)
// Uh-oh, an error occurred!
});
```
React
```jsx
const App = () => {
var listRef = firebase.storage().ref("sweet_gifts/");
const [list, setList] = React.useState([]);
const getList = () => {
listRef
.listAll()
.then((result) => {
result.items.forEach((ref) => {
ref.getDownloadURL().then((url) => {
setList((prevState) => [
...prevState,
{ url: url, name: ref.name }
]);
});
});
})
.catch(function (error) {
console.log(error);
// Uh-oh, an error occurred!
});
};
React.useEffect(() => {
getList();
}, []);
return (
<div>
<ul>
{list &&
list.map((val, idx) => (
<li>
<a href={val.url} download>{val.name}</a>
</li>
))}
</ul>
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#app"));
```
### [3] 下載檔案: 方法一 網址
```js
`https://storage.cloud.google.com/v0/b/${儲存空間位置}?alt=media&token=${token}`
```
儲存空間位置 gs://superior-6be2f.appspot.com/sweet_gifts/video_text_tracks.vtt

demo: https://firebasestorage.googleapis.com/v0/b/superior-6be2f.appspot.com/o/sweet_gifts%2Fvideo_text_tracks.vtt?alt=media&token=05dabbd9-a16a-4bac-b53e-64ada5f4055d
### [3] 下載檔案: 方法二 取得清單
使用 `firebase.storage().ref('sweet_gifts/').listAll()`
### [實作] CRUD
```jsx
var config = {
apiKey: "xxx",
authDomain: "superior-6be2f.firebaseapp.com",
databaseURL: "https://superior-6be2f.firebaseio.com",
projectId: "superior-6be2f",
storageBucket: "superior-6be2f.appspot.com",
messagingSenderId: "271709208420",
appId: "1:271709208420:web:dd51236022e7b83b360471",
measurementId: "G-HY6C29JEK6"
};
firebase.initializeApp(config);
const bucketName = "sweet_gifts";
function formatDate(date) {
return (
date.getFullYear() +
"/" +
(date.getMonth() + 1) +
"/" +
date.getDate() +
" " +
date.getHours() +
":" +
date.getMinutes()
);
}
function returnFileSize(number) {
if (number < 1024) {
return number + "bytes";
} else if (number >= 1024 && number < 1048576) {
return (number / 1024).toFixed(1) + "KB";
} else if (number >= 1048576) {
return (number / 1048576).toFixed(1) + "MB";
}
}
const App = () => {
var listRef = firebase.storage().ref("sweet_gifts/");
const [fileTxt, setFileTxt] = React.useState({});
const [fileInfo, setFileInfo] = React.useState({
lastModified: "",
lastModifiedDate: null,
name: "",
size: NaN,
type: "",
webkitRelativePath: ""
});
const [list, setList] = React.useState([]);
const storageRef = firebase.storage().ref(bucketName + "/" + fileInfo.name);
const deleteFile = (fileName) => {
// Delete the file
firebase
.storage()
.ref(bucketName)
.child(fileName)
.delete()
.then(function () {
// File deleted successfully
getList();
})
.catch(function (error) {
// Uh-oh, an error occurred!
});
};
const getList = () => {
setList([]);
listRef
.listAll()
.then((result) => {
result.items.forEach((ref) => {
ref.getDownloadURL().then((url) => {
setList((prevState) => [
...prevState,
{ url: url, name: ref.name }
]);
});
});
})
.catch(function (error) {
console.log(error);
// Uh-oh, an error occurred!
});
};
React.useEffect(() => {
getList();
}, []);
const handleSave = () => {
const bucketName = "sweet_gifts";
const storageRef = firebase.storage().ref(bucketName + "/" + fileInfo.name);
// Upload file
var task = storageRef.put(file);
// Upload Progress bar
task.on(
"state_changed",
function progress(snapshot) {
var percentage =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
// uploader.value = percentage;
},
function error(err) {},
function complete() {}
);
// task.on(firebase.storage.TaskEvent.STATE_CHANGED, () => {
// let downloadURL = task.snapshot.downloadURL;
// console.log("downloadURL", downloadURL);
// });
};
// uploadBtn.addEventListener("change", (event) => {
// handleSave(event);
// });
const handleChange = (e) => {
if (e.target.files[0]) {
const file = event.target.files[0];
setFileTxt(file);
setFileInfo((prevState) => ({
...prevState,
name: file.name,
lastModified:file.lastModified,
size:file.size,
type:file.type
}));
}
};
const handleUpload = () => {
// Upload file
const task = storageRef.put(fileTxt);
task.on(
"state_changed",
function progress(snapshot) {
var percentage =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
// uploader.value = percentage;
},
function error(err) {},
function complete() {
firebase
.storage()
.ref(bucketName)
.child(fileInfo.name)
.getDownloadURL()
.then((url) => {
console.log(url);
});
getList();
}
);
};
console.log(fileInfo);
return (
<div>
{/* <progress value="0" max="100" id="uploader">0%</progress>*/}
<input type="file" onChange={handleChange} />
<div>
<p>
<span>name</span> {fileInfo.name}
</p>
<p>
<span>lastModified</span> {new Date(fileInfo.lastModified).toJSON()}
</p>
<p>
<span>size</span> {returnFileSize(fileInfo.size)}
</p>
<p>
<span>type</span> {fileInfo.type}
</p>
</div>
<button onClick={handleUpload}>Upload</button>
<div id="msg"></div>
<ul>
{list &&
list.map((val, idx) => {
console.log(val);
return (
<li>
<a href={val.url} download>
{val.name}
</a>
<button onClick={() => deleteFile(val.name)}>x</button>
</li>
);
})}
</ul>
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#app"));
```