# 如何從雲端轉貼圖片到 DocuSky ?
## - *FireBase Storage服務 使用&設定教學*
<!-- 標籤 -->
###### tags: `使用導引`, `文件狀態:維護中`
<!-- 內文編輯更新資訊,若有更動此份文件內容,請更新此項資訊 -->
> [name=Kuan-Lin Chen, 陳冠霖]
> [time=Tue, Sep 2, 2020 1:11 AM]
<!-- 摘要 -->
:::success
<!-- 當前負責人使用高亮標示,新接替維護人員請加在第一個 -->
- **建立者**:陳冠霖
- **維護者**:==陳冠霖==
:::
<!-- 筆記正文開始 -->
:::info
***本文的連結都可以透過點擊 來看此格式連結結果***
:::
## 聯絡方式
有任何問題 或 有特殊設定的構想
可透過下列方式聯繫我
* FB : 搜尋 陳冠霖 or https://www.facebook.com/asdleon/
(回覆較快)
* E-mail : asdleonnn@gmail.com
(回覆可能較慢)
* 直接在本hackmd留言
(回復可能非常慢or非常快)
## 前情提要
如果 想轉貼圖片到DocuSky or 任何線上編輯及文件上
最簡單就是 上傳圖片到任何 **圖像平台**(imgur、imageshack...etc)
或者 **個人雲端服務**(google drive、mega nz、icloud...etc)
但是 上傳圖像得到的連結 都是不規則亂碼
有方法處理嗎? ...
## Why Firebase ?
**以下圖 Caturday.png 為例**
![](https://i.imgur.com/yEyUq08.png)
上傳到 imgur
會得到: https://i.imgur.com/yEyUq08.png
但是當有一百張圖片
Dom_001.png, Dom_002.png ... Dom_099.png, Dom_100.png
我們更希望能用像是
https://i.imgur.com/固定的參數/Dom_001.png
https://i.imgur.com/固定的參數/Dom_002.png
.
.
.
https://i.imgur.com/固定的參數/Dom_099.png
https://i.imgur.com/固定的參數/Dom_100.png
來存放自己的圖片
而不是紀錄一百個如 yEyUq08.png 的亂碼
或去Imgur上手動產生連結再貼上 重複個一百次 ...
而**Firebase經過設定**後 就可以達成這個需求了
## 事前準備
### Q1. 需要準備甚麼?
:::info
* **Answer:**
Firebase只接受Google帳號
沒有的話 請先註冊一個
:::
### Q2. 我需要會甚麼能力?
:::info
* **Answer:**
~~得需要藉由 Security Rules language 語法更動設定檔案,來讓外部網路存取程式化以 ...~~
放心~~ 已經提供設定碼 只要會**複製貼上**就可以了
:::
## 開始設定
FireBase提供多種服務,此次只會用到storage
其提供的Security Rules language來對存取邏輯進行設計
來達到我們期望的
https://xxx.com/某些固定的參數/自己的命名.jpg/另些固定的參數
下面會依序 step by step 解說
---
### 開啟 Firebase Storage 服務
1. **找到官網**(google 搜尋 firebase)
**或 https://firebase.google.com/
並點選右上 登入**![](https://i.imgur.com/hIzwQEJ.png)
:::warning
如果右上已經有登入的google帳號 可以直接跳到 step3
:::
2. **登入google帳號**![](https://i.imgur.com/LAVlL9X.png)
3. **選右上 前往主控台**![](https://i.imgur.com/Kpbmjda.png)
4. **點選建立專案**![](https://i.imgur.com/SM8L2Gr.png)
5. **輸入自定義專案名稱 並點選接受條款**![](https://i.imgur.com/z3aj69n.png)
:::warning
如果名稱已有人使用 會自動加上後贅編碼
:::
6. **取消 "啟用這項專案的 Google Analytics (分析) 功能" 直接建立專案**
![](https://i.imgur.com/21jA1k6.png)
:::warning
不取消的話 只是會單純多一個步驟去選分析地點
:::
7. **等待其跑完**![](https://i.imgur.com/rBCxFQ0.png)
8. **點選左邊選單中的 開發**![](https://i.imgur.com/5tXqf1D.png)
**點選下拉選單中的 Storage**
![](https://i.imgur.com/KmLTOIR.png)
9. **點擊 開啟使用**![](https://i.imgur.com/xmTCyA8.png)
**點擊下一步** ![](https://i.imgur.com/trM5Qvg.png)
**將Cloud Storage選成 asia-east2**![](https://i.imgur.com/onSNSqf.png)
![](https://i.imgur.com/RspZsEB.png)
:::warning
這是設定雲端儲存的資料站位置 基本選東亞2站
如果有額外需求 可以根據自己地區改選
p.s. 選擇位置**可能**影響傳輸速率
:::
10. **進入管理頁面如下**![](https://i.imgur.com/L8btwOi.png)
**Files** : 上傳管理資料及資料夾
**Rules** : 可程式化 管理自己資料庫的外部存取邏輯
**Usage** : 顯示使用的空間大小 本日存取檔案次數 本日流量![](https://i.imgur.com/tneAcWd.png)
---
### **如何開始設定 Firebase Storage 規則**
* **在上方工作選單中選擇Rules**
![](https://i.imgur.com/r693UjF.png)
**便能看到其設定區域 原始碼如下**
![](https://i.imgur.com/cToKfjO.png)
```
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
```
---
## 設定規則
:::info
接下來會以Firebase的**Security Rules language**編寫rules
**不需要**理解其設定語法
下面已**直接提供程式碼** 只要**複製貼上**即可
*(有興趣者 可以前往 https://firebase.google.com/docs/storage/security/core-syntax?hl=en
查閱其規則及延伸應用)*
:::
下面提供兩個方法 可直接**點擊**跳轉頁面
1. [**開放特定資料夾供讀取**](#第一種設定法:%2d開放特定資料夾供讀取) : **只有特定資料夾底下的檔案 才可以被外部讀取**
2. [**開放所有檔案供讀取**](#第二種設定法:%2d開放所有檔案供讀取) : **所有檔案都可以被外部讀取**
:::danger
!!! 注意 !!!
此類設定相對較危險 & 不適合放不想公開的私人檔案
但設定和管理方便一點點 & 想新增公開資料夾也不用設定
:::
---
## 第一種設定法: 開放特定資料夾供讀取
1. **在檔案管理頁面 Files 中 點選新增資料夾按鈕**
![](https://i.imgur.com/IUhcuLx.png)
![](https://i.imgur.com/ieAMiZO.png) **中間有+號icon的那個**
2. **輸入自訂資料夾名稱**
(範例為 Opened_dir)
![](https://i.imgur.com/bk00vUt.png)
3. **返回Rules頁面 將設定碼改成下述**
(直接複製貼上)
```
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{dir}/{allPaths=**} {
allow read : if dir == "Opened_dir";
}
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
```
:::warning
記得將第五行 allow read : if dir == "Opened_dir";
裡面的 Opened_dir 改成 自己設定的資料夾名稱
:::
4. **點擊發布**
![](https://i.imgur.com/KRmFcEl.png)
:::success
這樣就完成設定 在Opened_dir底下的檔案可直接存取 不需要token或手動連結
同時 資料夾外的檔案保持無法直接存取
*p.s.* 更改rules可能會等數分鐘系統才會套用 剛剛改完後不能連結為正常現象
:::
---
## 第二種設定法: 開放所有檔案供讀取
:::danger
!!! 注意 !!!
這個設定會使Firebase中所有檔案都可以被外部讀取
:::
1. **進入Rules頁面 將設定碼改成下述**
(直接複製貼上)
```
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow write: if request.auth != null;
allow read;
}
}
}
```
2. **點擊發布**
![](https://i.imgur.com/oOCkEpm.png)
* **現在所有檔案都可以不需要token進行存取了**
---
## **額外工具 : 套用公式的Excel**
* **為何需要這個工具 ? :**
要一直手動更改url ...
還得自己記錄前後固定的網址部分 ...
甚至要處理 \/ 轉換成ascii的 %2F ...
* **達成的結果 :**
只需要輸入**一次**自己的固定網址 之後只要輸入圖片名稱 就可以得到網址了
* **下載連結 :** [**點我**](https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Ffirebase%E6%AA%94%E6%A1%88%E9%80%A3%E7%B5%90%E7%94%9F%E6%88%90.xlsx?alt=media)
(跟本文圖片放置同一Firebase中 無法下載請參照[**聯繫**](#聯絡方式))
:::info
excel內預設的檔案連結範例 為本文中的範例otter_1.jpg
:::
* **下面將逐步解說如何使用**
1. **設定區域**![](https://i.imgur.com/CXIawTH.png)
**根據指示填上 個人固定網域名直至 /o**
如 : https://firebasestorage.googleapis.com/v0/b/專案id.appspot.com/o
2. **填上資料夾名稱** (若無則改成空白)
3. **在檔名欄填上檔名**
![](https://i.imgur.com/nTOX5CN.png)
4. **檔名連結@url欄 會自動產生對應的檔案連結**![](https://i.imgur.com/M37usdB.png)
:::warning
產生的檔案url 為超連結格式 可以將公式替換成設定區域中的
![](https://i.imgur.com/iOcxBhC.png)
非超連結用
:::
---
## **延伸閱讀**
**(\*可略)**
:::warning
此區內為延伸閱讀 紀錄firebase的資料存取概念
**沒有** 設定相關的操作
設定可直接點擊右邊跳到 [**開始設定**](#開始設定)
:::
---
### **延伸01 : 如何確定自己的圖片存取權限設定正常?**
:::info
下面會用範例來示範存取權限 是否正常
**沒有** 設定相關的操作
設定可直接點擊右邊跳到 [**開始設定**](#開始設定)
:::
---
1. **上傳兩張圖 cat_1.jpg cat_2.jpg 在資料夾外**![](https://i.imgur.com/SIkWyBN.png)
**上傳兩張圖 otter_1.jpg otter_2.jpg 在資料夾 Opened_dir 內**![](https://i.imgur.com/sCB27I1.png)
2. **以原本流程 點擊 超連結: otter_1.jpg 得到 direct link:** https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_1.JPG?alt=media&token=55a39e27-04d5-4cac-be63-c04ea4f717a8
3. **去除其 token(如下) 並點擊 證明無token連結 讀取圖片正常運作**
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_1.JPG?alt=media
![](https://i.imgur.com/fxc8hKe.jpg)
4. **拆解分析連結**
https://firebasestorage.googleapis.com/v0/b
/klchen-f9d45.appspot.com
/o
/Opened_dir%2Fotter_1.JPG
?alt=media
* **可以發現第四行: Opened_dir%2Fotter_1.JPG
正是剛剛我們設定的資料夾名稱(Opened_dir) + %2F + otter_1.JPG**
:::success
以此類推 將 otter_1.JPG 抽換成 otter_2.JPG
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_2.JPG?alt=media
就能成功連結到圖片 otter_2.JPG 了
![](https://i.imgur.com/dBfvWk7.png)
:::
:::info
%2F 其實是 / 的編碼
所以 Opened_dir%2Fotter_1.JPG
其實就是 Opened_dir/otter_1.JPG
但是直接用 / 會造成網頁解碼錯誤
所以如果是 **資料夾1** 裡面的 **資料夾2** 裡面的 **照片1.jpg**
用 **資料夾1** %2F **資料夾2** %2F **照片1.jpg** 便可連結
:::
* **下面會檢查資料夾外的圖片 cat_1.jpg cat_2.jpg 是不是隱私的**
根據前面的
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_2.JPG?alt=media
將其改成 cat_2.jpg版本
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_2.jpg?alt=media
會發現其拒絕存取
只能依照原本的方法 用點擊超連結來取得 有token的版本
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_2.jpg?alt=media&token=d0a6cfd9-b2d1-4ff1-943a-4f757e515d1c
才可以連線
而此連結改成 cat_1.jpg 也無法連結
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_1.jpg?alt=media&token=d0a6cfd9-b2d1-4ff1-943a-4f757e515d1c
---
### **延伸02 : Firebase預設圖片連結到底怎麼運作?**
:::info
下面會用案例說明 Firebase圖片預設取用方式
**沒有** 設定相關的操作
設定可直接點擊右邊跳到 [**開始設定**](#開始設定)
:::
**預設取得照片的直接連結(direct link)**
1. **上傳兩個檔案 cat_1.jpg cat_2.jpg 並點選cat1.jpg**![](https://i.imgur.com/7cdqmLL.png)
2. **點擊 超連結: cat_1.jpg**![](https://i.imgur.com/L0HWeMd.png)
3. **跳到新網頁如下**![](https://i.imgur.com/m8bfNEY.png)
4. **從上方網址區可得到direct link**![](https://i.imgur.com/9FYi979.png)
---
* **下面會稍微解析一下得到的direct link**
---
得到的direct link如下:
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_1.jpg?alt=media&token=9b91572e-dce0-404b-8c84-bbd657b0d8ca
將其稍微拆解分析
https://firebasestorage.googleapis.com/v0/b
/klchen-f9d45.appspot.com
/o
/cat_1.jpg
?alt=media
token=9b91572e-dce0-404b-8c84-bbd657b0d8ca
理想狀態是將第四行的cat_1.jpg 抽換成 cat_2.jpg便可以直接存取別張照片
如下示:
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_2.jpg?alt=media&token=9b91572e-dce0-404b-8c84-bbd657b0d8ca
但是實際上卻無法依此連結 cat_2.jpg
而真正照流程走一遍 超連結cat_2.jpg
![](https://i.imgur.com/h9JD688.png)
產生的正確direct link:
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_2.jpg?alt=media&token=d0a6cfd9-b2d1-4ff1-943a-4f757e515d1c
比較後發現 token是完全不同的
而其看起來也不固定或可被計算出
捨去token的連結也無法運作
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/cat_2.jpg?alt=media
如何讓檔案能用下面的方式直接存取
https://firebasestorage.googleapis.com/v0/b/你的專案id/o/你命名的圖片名稱?alt=media
而不用去處理token 請參照 [**設定規則**](#設定規則)
---
## **常見 Q&A**
### Q1. 手動更改url來編輯檔案路徑好麻煩,而且很容易忘記自己的網域名,以及一些雖然固定但看起來像亂碼的東西...
:::info
* **Answer:**
1. 可以參照 [**額外工具 : 套用公式的Excel**](#額外工具%2d:%2d套用公式的Excel) 來使用工具幫助處理
2. 用預設的取得連結方法,開啟資料夾內的其中一個檔案,得到路徑後去除token,就可以得到資料夾的路徑
接著只要更改檔名部分。
* **詳情請見** - [**延伸02 : Firebase預設圖片連結到底怎麼運作?**](#延伸02%2d:%2dFirebase預設圖片連結到底怎麼運作?)
:::
### Q2. Firebase穩定及安全嗎? 其主要服務到底是甚麼?
:::info
* **Answer:**
Firebase是行動和網路應用程式開發者的平台,始於2011年,並在2014年被google收購,目前有約150萬個應用程式採用此平台,我們這次只是使用其storage雲端儲存的部分服務,其儲存位置為google伺服器站。也就是**其安全穩定程度很高,尤其是storage服務,可視為跟Google Drive、Google Cloud Platform同層級**。
* **詳情請見** - [**Firebase Wiki**](https://zh.wikipedia.org/wiki/Firebase)
:::
### Q3. Firebase免費用戶的限制在哪方面? 其向上收費價格是?
:::info
* **Answer:**
下面將只針對**Storage服務**進行列表
(付費用戶 一樣能享有免費用戶的每日額度 屬於**超額收費機制**)
*p.s.* 價錢和免費用量可能浮動 請以官網公告為準
---
* **免費用戶**
* 空間大小: 5GB
* 下載流量: 每天1GB
* 上傳次數: 每天2萬次
* 下載次數: 每天5萬次
* **付費價格**
* 空間大小: 1GB = 0.026美金
* 下載流量: 1GB = 0.012美金
* 上傳次數: 1萬次 = 0.005美金
* 下載次數: 1萬次 = 0.0004美金
---
* **詳情請見** - [**Firebase Pricing**](https://firebase.google.com/pricing?authuser=0)
:::
### Q4. Firebase免費額度用完後會不會直接扣錢?
:::info
* **Answer:**
免費用戶統一為 **spark服務**,在沒升級服務前,用完額度不會扣款(即便google帳戶已綁定信用卡),只會停止當日使用
*p.s.* 用戶服務可能更改名稱 請以官方公告為準
* 詳情請見 - [**Firebase常見問題 : 價錢**](https://firebase.google.com/support/faq?authuser=0#pricing)
:::
### Q5. 怎麼知道今天用了多少額度或者過去使用紀錄?
:::info
* **Answer:**
請點選 **Usage** 進入頁面
![](https://i.imgur.com/6oQFaZU.png)
便可看到報表如下
![](https://i.imgur.com/KS0xiyi.png)
報表為數小時更新一次 **並非**完全及時更新
:::
### Q6. 為什麼我連結一直跑到一堆文字的畫面?
:::info
* **Answer:**
如果檔案路徑是正確的話
請檢查一下連結最尾端有沒有加上 **?alt=media**
以前面 otter_2.jpg 為例子
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_2.JPG
會導引至下圖畫面![](https://i.imgur.com/66iDCho.png)
而加上 **?alt=media**
https://firebasestorage.googleapis.com/v0/b/klchen-f9d45.appspot.com/o/Opened_dir%2Fotter_2.JPG?alt=media
才是正確的圖片 direct link
![](https://i.imgur.com/dBfvWk7.png)
:::
### Q7. 檔案沒辦法能從外面更改內容嗎?
:::info
* **Answer:**
剛剛上面的設定都只跟read(讀取)有關,想要新增的話,要在設定中來編寫有關write的部分。
大致為將
allow read;
改成
allow read, write;
:::
:::danger
!!! 注意 !!!
這會導致儲存在雲端的檔案可能被任意竄改
:::
### Q8. 想要公開的資料夾不只一個怎麼辦?
:::info
* **Answer:**
**只公開一個資料夾的設定碼 大致如下**
```
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{dir}/{documentId} {
allow read : if dir == "原本的公開資料夾名稱";
}
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
```
**加上**
```
match /{dir}/{documentId} {
allow read : if dir == "新增的公開資料夾名稱";
}
```
**將其擴充改成**
```
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{dir}/{documentId} {
allow read : if dir == "原本的公開資料夾名稱";
}
match /{dir}/{documentId} {
allow read : if dir == "新增的公開資料夾名稱";
}
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
```
需要兩個資料夾以上的話 以此類推
*p.s.* 可直接複製貼上 再把 **原本的公開資料夾名稱** 以及 **新增的公開資料夾名稱** 改成自己設定的
:::