เปิด billing และ deploy cloud function
เปิด Billing
เพื่อให้สามารถทำการ deploy cloud function ได้เราจำเป็นต้องเปิด Billing
หากเรายังไม่เปิด billing และลอง deploy functions ด้วยคำสั่งนี้ดู (เข้าไปใน folder functions)
# จะใช้คำสั่งนี้ที่เก็บไว้ใน package.json
npm run deploy
# หรือใช้คำสั่งเต็มอันนี้
firebase deploy --only functions
จะเจอ Error นี้ออกมา
ซึ่ง Cloud functions (ตั้งแต่ v2 เป็นต้นมา) นั้นจะต้องเปิด billing เพื่อให้ deployment ของ Cloud function สามารถทำงานได้
ให้กดตรง Upgrade > แล้วเลือกเป็น Plan "Pay as you go" แทน และทำการผูก Billing กับ Firebase ไว้
เมื่อผูกเสร็จเรียบร้อย ตรงด้านล่างข้อความจะเปลี่ยนไป
** สามารถปิดกลับมา billing แบบ Free plan ได้ตลอดเวลา หากไม่แน่ใจสามารถปรับกลับมาได้ แต่จะส่งผลทำให้ cloud functions กลับมาใช้งานไม่ได้
Deploy function
ทีนี้ก่อนจะ deploy จริง เราจะมาทำการแก้ path ให้ทุก path ขึ้นตอนด้วย /api
กันก่อน เนื่องจากตรง exports.api
นั้นเป็นเพียงชื่อ functions หากขึ้น cloud functions ไปทั้งแบบนี้ domain จริงจะกลายเป็น
domain.com/webhook
domain.com/placeorder
domain.com/test
ซึ่งมันจะส่งผลทำให้เราไม่สามารถทำ proxy บน Firebase hosting ได้ (เหมือนที่เราทำ proxy กับ Vue)
ดังนั้นเราจึงจำเป็นต้องแก้ url ให้ทุก path ขึ้นต้นด้วย api ก่อน (จะใช้ท่า group ของ express ก็ได้ในกรณีมี api จำนวนมาก)
ที่ functions/index.js
เราจะเพิ่มแค่ 2 API คือ placeorder และ test (ที่เป็น API ที่เราจะทดสอบยิงจริงจากหน้าบ้าน)
// เพิ่ม /api นำหน้าทุกอันที่เกี่ยวข้องกับหน้าบ้าน
app.post('/api/placeorder', async (req, res) => {
/* ไม่ต้องแก้ code อะไร */
})
app.post('/api/test', async (req, res) => {
/* ไม่ต้องแก้ code อะไร */
})
exports.api = onRequest(app)
จากนั้นให้เราทำการ deploy ขึ้นด้วยคำสั่งเดิมกับที่ Error ก่อนหน้านี้
firebase deploy --only functions
เมื่อผลลัพธ์ว่า Deploy successful = Deploy เสร็จแล้วเรียบร้อย
ให้ไปสำรวจที่เมนู Functions ของ Firebase ว่าขึ้นเรียบร้อยแล้วหรือไม่
ตัว Cloud functions จะแสดง url ที่สามารถยิงได้ออกมาให้ทดสอบยิงเข้าไปที่ domain (ตามที่ระบุ) แล้วตามด้วย path (เช่นเคสนี้ https://api-643iqq2nka-uc.a.run.app ก็จะยิงไปที่ https://api-643iqq2nka-uc.a.run.app/api/test)
ถ้าสามารถยิงข้อมูลออกมาได้ = Cloud function เชื่อมและ deploy แล้วเรียบร้อย
หากใคร เจอ Error “Your client does not have permission to get URL from this server” ระหว่างการ deploy Cloud function
- คำแนะนำตาม stackoverflow คือ เกิดขึ้นจากการ assign สิทธิระหว่าง deploy ซึ่งเป็นไปได้จากการใช้ firebase-cli ที่ version เก่าไป
- ให้ลองทำการ update
npm install -g firebase-tools
แล้วลองทำการ deploy ซ้ำดูอีกรอบ - แนะนำให้ลบ functions ก่อนการ deploy ซ้ำจากใน Firebase ก่อน
ุสุดท้าย เปลี่ยน url webhook ที่ Omise ให้เป็น domain เดียวกันกับ cloud fuctions
เพิ่ม proxy hosting และ Deploy hosting ใหม่
Ref: https://firebase.google.com/docs/hosting/full-config
กลับมาที่ Firebase hosting นอกจากจะสามารถ hosting static content (พวก html, css, js) ได้แล้ว มันสามารถ hosting dynamic content อย่าง
- Cloud functions = ต่อเป็น HTTP server, render dynamic content
- redirect rule = สามารถ set redirect ไปยังหน้าอื่น
- Cloud run = ต่อเป็น HTTP server เข้า Cloud run (จะทำให้เราสามารถทำ Backend จากภาษาอะไรก็ได้)
ซึ่งทุกอย่างจะทำผ่าน firebase.json
ใน key hosting ในเคสนี้เราจะ
- ทำการ binding path
/api
ของหน้าเว็บ เข้ากับ/api
ของ Cloud function (ทีี่เราพึ่ง deploy ไป) - ซึ่งชื่อ functions ที่เรา deploy ไปนั้นชื่อ
api
(สามารถ เปลี่ยนได้จากการexports.<ชื่อ functions>
ใน cloud functions) - ให้นำชื่อ functions มาระบุคู่กับ path ใน config ของ firebase hosting
ที่ firebase.json
{
"hosting": {
"public": "dist",
// เพิ่ม rewrite path เข้ามา
"rewrites": [
{
"source": "/api/*", // path หลัง /api ทั้งหมด
"function": {
"functionId": "api", // ชื่อ service
"region": "us-central1"
}
},
{
"source": "**", // เพิ่มสิ่งนี้เพื่อให้ทำงานแบบ Single Page application ได้
"destination": "/index.html"
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
// ที่เหลือเหมือนเดิม
}
หลังจากนั้นทำการ deploy ขึ้น hosting ด้วยคำสั่งเดิม
firebase deploy --only hosting
เมื่อ deploy สำเร็จ ทำการทดสอบยิง API โดยเปลี่ยนมายิงที่ domain ของ hosting แทน
เช่น ตัวอย่างใน session นี้ domain ที่แสดงออกมาคือ https://easy-commerce-workshop.web.app เราจะทำการยิงไปยัง https://easy-commerce-workshop.web.app/api/test (Path test เดียวกันกับที่ยิงใน cloud functions)
แปลว่า การผูก /api เข้ากับ Cloud functions ถูกต้องเรียบร้อย
ให้ลองทดสอบชำระเงินจากหน้าเว็บหลัก (เล่นจนจบ flow ทั้งหมดได้เลย)
หากไม่ติดอะไร สามารถชำระเงินได้ > สามารถได้ status success จาก webhook ได้
= การ deploy ทุกอย่างเราเสร็จสิ้นแล้ว
เพิ่มเติมการดู Log ใน Cloud functions
Cloud functions ได้ทำการส่ง log มาไว้ใน Logs Explorer ของ Google Cloud สามารถกดเข้าได้จาก View Logs ใน service นั้นๆของ Cloud functions
จากนั้นจะ ขึ้นเป็นหน้า log มาจะสามารถดูตามช่วงเวลา และดู Error ที่เกิดขึ้นได้ (รวมถึงการใช้ console.log ก็จะมาโผล่ที่นี่เช่นเดียวกัน)