Skip to main content

เปิด billing และ deploy cloud function

เปิด Billing

เพื่อให้สามารถทำการ deploy cloud function ได้เราจำเป็นต้องเปิด Billing

หากเรายังไม่เปิด billing และลอง deploy functions ด้วยคำสั่งนี้ดู (เข้าไปใน folder functions)

# จะใช้คำสั่งนี้ที่เก็บไว้ใน package.json
npm run deploy

# หรือใช้คำสั่งเต็มอันนี้
firebase deploy --only functions

จะเจอ Error นี้ออกมา

function-01

ซึ่ง Cloud functions (ตั้งแต่ v2 เป็นต้นมา) นั้นจะต้องเปิด billing เพื่อให้ deployment ของ Cloud function สามารถทำงานได้

ให้กดตรง Upgrade > แล้วเลือกเป็น Plan "Pay as you go" แทน และทำการผูก Billing กับ Firebase ไว้

function-02

function-03

เมื่อผูกเสร็จเรียบร้อย ตรงด้านล่างข้อความจะเปลี่ยนไป

function-04

function-05

** สามารถปิดกลับมา 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 เสร็จแล้วเรียบร้อย function-06

ให้ไปสำรวจที่เมนู Functions ของ Firebase ว่าขึ้นเรียบร้อยแล้วหรือไม่

function-07

function-08

ตัว Cloud functions จะแสดง url ที่สามารถยิงได้ออกมาให้ทดสอบยิงเข้าไปที่ domain (ตามที่ระบุ) แล้วตามด้วย path (เช่นเคสนี้ https://api-643iqq2nka-uc.a.run.app ก็จะยิงไปที่ https://api-643iqq2nka-uc.a.run.app/api/test)

function-09

ถ้าสามารถยิงข้อมูลออกมาได้ = Cloud function เชื่อมและ deploy แล้วเรียบร้อย

caution

หากใคร เจอ 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 ก่อน function-13

Ref: https://stackoverflow.com/questions/47511677/firebase-cloud-function-your-client-does-not-have-permission-to-get-url-200-fr

ุสุดท้าย เปลี่ยน url webhook ที่ Omise ให้เป็น domain เดียวกันกับ cloud fuctions

function-14

เพิ่ม 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)

function-10

แปลว่า การผูก /api เข้ากับ Cloud functions ถูกต้องเรียบร้อย

ให้ลองทดสอบชำระเงินจากหน้าเว็บหลัก (เล่นจนจบ flow ทั้งหมดได้เลย)

function-11

หากไม่ติดอะไร สามารถชำระเงินได้ > สามารถได้ status success จาก webhook ได้

= การ deploy ทุกอย่างเราเสร็จสิ้นแล้ว

เพิ่มเติมการดู Log ใน Cloud functions

Cloud functions ได้ทำการส่ง log มาไว้ใน Logs Explorer ของ Google Cloud สามารถกดเข้าได้จาก View Logs ใน service นั้นๆของ Cloud functions

function-15

จากนั้นจะขึ้นเป็นหน้า log มาจะสามารถดูตามช่วงเวลา และดู Error ที่เกิดขึ้นได้ (รวมถึงการใช้ console.log ก็จะมาโผล่ที่นี่เช่นเดียวกัน)

function-12