keyboard_tabSkip to content
listVue Firebase Masterclass

เปิด billing และ deploy cloud function

สารบัญ

เปิด Billing

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

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

bash
# จะใช้คำสั่งนี้ที่เก็บไว้ใน 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 ที่เราจะทดสอบยิงจริงจากหน้าบ้าน)

javascript
// เพิ่ม /api นำหน้าทุกอันที่เกี่ยวข้องกับหน้าบ้าน 
app.post('/api/placeorder', async (req, res) => {
  /* ไม่ต้องแก้ code อะไร */
})

app.post('/api/test', async (req, res) => {
  /* ไม่ต้องแก้ code อะไร */
})

exports.api = onRequest(app)

จากนั้นให้เราทำการ deploy ขึ้นด้วยคำสั่งเดิมกับที่ Error ก่อนหน้านี้

bash
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

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 ด้วยคำสั่งเดิม

bash
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