Xây dựng ứng dụng web truy cập thiết bị

1. Giới thiệu

Chương trình Quyền sử dụng thiết bị cung cấp Smart Device Management API, một API REST để nhà phát triển điều khiển các thiết bị Google Nest từ ứng dụng của họ. Người dùng cần đồng ý cho phép bên thứ ba truy cập vào thiết bị Nest của họ.

52f77aa38cda13a6.png

Có 3 bước chính để tích hợp thành công Quyền sử dụng thiết bị:

  1. Tạo dự án – Tạo một dự án trong Google Cloud Platform và đăng ký làm nhà phát triển trong Bảng điều khiển quyền sử dụng thiết bị.
  2. Liên kết tài khoản – Thu hút người dùng thông qua quy trình liên kết tài khoản và truy xuất mã truy cập. Trao đổi mã này để lấy mã truy cập.
  3. Device Control – Thực hiện các yêu cầu Smart Device Management API để điều khiển thiết bị bằng cách gửi lệnh bằng mã truy cập.

Trong Lớp học lập trình này, chúng ta sẽ nghiên cứu chuyên sâu về cách hoạt động của Quyền sử dụng thiết bị bằng cách xây dựng một ứng dụng web xử lý hoạt động xác thực và thực hiện các Lệnh gọi API Smart Device Management. Chúng ta cũng sẽ tìm hiểu cách triển khai một máy chủ proxy đơn giản bằng Node.js và Express để định tuyến các yêu cầu Quyền sử dụng thiết bị.

Trước khi bắt đầu, bạn nên tìm hiểu kỹ về các công nghệ web phổ biến mà chúng ta sẽ sử dụng trong Lớp học lập trình này, chẳng hạn như xác thực bằng OAuth 2.0 hoặc tạo ứng dụng web bằng Node.js, mặc dù đây không phải là điều kiện tiên quyết.

Những thông tin bạn cần

  • Node.js 8 trở lên
  • Tài khoản Google có liên kết với Nest Thermostat

Kiến thức bạn sẽ học được

  • Thiết lập một dự án Firebase lưu trữ các trang web tĩnh và hàm trên đám mây
  • Đưa ra yêu cầu truy cập vào thiết bị thông qua một ứng dụng web dựa trên trình duyệt
  • Tạo một máy chủ proxy bằng Node.js và Express để định tuyến các yêu cầu của bạn

2. Tạo dự án

Nhà phát triển cần tạo một dự án trên Google Cloud Platform (GCP) để thiết lập chế độ tích hợp Quyền sử dụng thiết bị. Mã ứng dụng kháchKhoá bí mật ứng dụng khách được tạo trong dự án GCP sẽ được dùng trong quy trình OAuth giữa ứng dụng của nhà phát triển và Google Cloud. Nhà phát triển cũng cần truy cập vào Bảng điều khiển quyền sử dụng thiết bị để tạo một Dự án nhằm truy cập vào Smart Device Management API.

Google Cloud Platform

Truy cập vào Google Cloud Platform. Nhấp vào tạo dự án mới rồi nhập tên dự án. Mã dự án [GCP-Project-Id] cho Google Cloud cũng sẽ xuất hiện, vui lòng ghi lại mã này vì chúng ta sẽ sử dụng mã này trong quá trình thiết lập Firebase. (Chúng ta sẽ gọi mã nhận dạng này là [GCP-Project-Id] trong suốt Lớp học lập trình này.)

585e926b21994ac9.png

Bước đầu tiên là bật Thư viện API cần thiết cho dự án của chúng ta. Chuyển đến APIs & Services > Library (API và dịch vụ > Thư viện) rồi tìm Smart Device Management API. Bạn cần bật API này để uỷ quyền cho dự án của mình thực hiện các yêu cầu đối với lệnh gọi API Quyền sử dụng thiết bị.

14e7eabc422c7fda.png

Trước khi chuyển sang bước tạo thông tin đăng nhập OAuth, chúng ta cần định cấu hình màn hình xin phép bằng OAuth cho dự án của mình. Chuyển đến API và Dịch vụ > Màn hình xin phép bằng OAuth. Đối với User Type (Loại người dùng), hãy chọn external (bên ngoài). Cung cấp tên và email hỗ trợ cho ứng dụng của bạn, cũng như thông tin liên hệ của nhà phát triển để hoàn tất màn hình đầu tiên. Khi được yêu cầu cung cấp Người dùng kiểm thử, hãy nhớ cung cấp địa chỉ email có các thiết bị được liên kết ở bước này.

Sau khi định cấu hình màn hình xin phép bằng OAuth, hãy chuyển đến API và Dịch vụ > Thông tin đăng nhập. Nhấp vào +Tạo thông tin xác thực rồi chọn Mã ứng dụng khách OAuth. Đối với loại ứng dụng, hãy chọn Ứng dụng web.

5de534212d44fce7.png

Nhập tên cho khách hàng của bạn rồi nhấp vào TẠO. Sau này, chúng ta sẽ thêm Nguồn gốc JavaScript được uỷ quyền và URI chuyển hướng được uỷ quyền. Sau khi hoàn tất quy trình này, [Client-Id][Client-Secret] được liên kết với Ứng dụng OAuth 2.0 này sẽ xuất hiện.

e6a670da18952f08.png

Bảng điều khiển quyền sử dụng thiết bị

Truy cập vào Bảng điều khiển quyền sử dụng thiết bị. Nếu chưa từng sử dụng Bảng điều khiển quyền sử dụng thiết bị, bạn sẽ thấy thoả thuận Điều khoản dịch vụ và khoản phí đăng ký là 5 USD.

Tạo một dự án mới và đặt tên cho dự án đó. Trong cửa sổ tiếp theo, hãy cung cấp [Client-Id] mà bạn nhận được từ GCP ở bước trước.

f8a3f27354bc2625.png

Khi bật sự kiện và hoàn tất các bước tạo dự án, bạn sẽ được chuyển đến trang chủ của dự án. [Project-Id] sẽ xuất hiện bên dưới tên mà bạn đã đặt cho dự án.

db7ba33d8b707148.png

Vui lòng lưu ý [Project-Id] vì chúng tôi sẽ sử dụng mã này khi gửi yêu cầu đến Smart Device Management API Quản lý.

3. Thiết lập Firebase

Firebase giúp nhà phát triển triển khai ứng dụng web một cách nhanh chóng và dễ dàng. Chúng ta sẽ phát triển một ứng dụng web phía máy khách để tích hợp Quyền sử dụng thiết bị bằng Firebase.

Tạo dự án Firebase

Truy cập vào Bảng điều khiển của Firebase. Nhấp vào Add Project (Thêm dự án), rồi chọn dự án mà bạn đã tạo ở bước Project Creation (Tạo dự án). Thao tác này sẽ tạo một dự án Firebase và dự án này sẽ được liên kết với dự án GCP [GCP-Project-Id].

Sau khi tạo thành công dự án Firebase, bạn sẽ thấy màn hình sau:

dbb02bbacac093f5.png

Cài đặt Firebase Tools

Firebase cung cấp một bộ công cụ CLI để tạo và triển khai ứng dụng của bạn. Để cài đặt các công cụ này, hãy mở một cửa sổ dòng lệnh mới và chạy lệnh sau. Thao tác này sẽ cài đặt các công cụ Firebase trên toàn cầu.

$ npm i -g firebase-tools

Để xác minh rằng bạn đã cài đặt đúng các công cụ firebase, hãy kiểm tra thông tin phiên bản.

$ firebase --version

Bạn có thể đăng nhập vào các công cụ CLI của Firebase bằng Tài khoản Google thông qua lệnh đăng nhập.

$ firebase login

Khởi chạy Dự án lưu trữ

Sau khi đăng nhập được, bước tiếp theo là khởi tạo một dự án lưu trữ cho ứng dụng web của bạn. Trên thiết bị đầu cuối, hãy chuyển đến thư mục nơi bạn muốn tạo dự án rồi chạy lệnh sau:

$ firebase init hosting

Firebase sẽ hỏi bạn một số câu hỏi để giúp bạn bắt đầu với một dự án lưu trữ:

  1. Vui lòng chọn một lựa chọn – Sử dụng một dự án hiện có
  2. Chọn một dự án Firebase mặc định cho thư mục này – Chọn ***[GCP-Project-Id]***
  3. Bạn muốn sử dụng thư mục nào làm thư mục công khai? – Công khai
  4. Định cấu hình dưới dạng ứng dụng một trang? – Có
  5. Thiết lập quy trình tạo và triển khai tự động bằng GitHub? – Không

Sau khi khởi chạy dự án, bạn có thể triển khai dự án đó lên Firebase bằng lệnh sau:

$ firebase deploy

Firebase sẽ quét dự án của bạn và triển khai các tệp cần thiết vào dịch vụ lưu trữ đám mây.

fe15cf75e985e9a1.png

Khi mở URL lưu trữ trong trình duyệt, bạn sẽ thấy trang mà bạn vừa triển khai:

e40871238c22ebe2.png

Giờ bạn đã biết những kiến thức cơ bản về cách triển khai một trang web bằng Firebase, hãy bắt đầu triển khai mẫu Codelab của chúng ta!

4. Mẫu lớp học lập trình

Bạn có thể sao chép kho lưu trữ lớp học lập trình được lưu trữ trên GitHub bằng lệnh bên dưới:

$ git clone https://github.com/google/device-access-codelab-web-app.git

Trong kho lưu trữ này, chúng tôi cung cấp các mẫu trong 2 thư mục riêng biệt. Thư mục codelab-start có các tệp cần thiết để bạn bắt đầu từ thời điểm hiện tại trong Lớp học lập trình này. Thư mục codelab-done chứa phiên bản hoàn chỉnh của Lớp học lập trình này, với máy chủ node.js và ứng dụng hoàn toàn có thể hoạt động.

Chúng ta sẽ sử dụng các tệp trong thư mục codelab-start trong suốt lớp học lập trình này. Tuy nhiên, nếu cảm thấy khó khăn, bạn cũng có thể tham khảo phiên bản codelab-done.

Tệp mẫu của lớp học lập trình

Cấu trúc tệp của thư mục codelab-start như sau:

public
├───index.html
├───scripts.js
├───style.css
firebase.json

Thư mục công khai chứa các trang tĩnh của ứng dụng. firebase.json chịu trách nhiệm định tuyến các yêu cầu trên web đến ứng dụng của chúng tôi. Trong phiên bản codelab-done, bạn cũng sẽ thấy một thư mục functions chứa logic để máy chủ proxy (express) của chúng tôi được triển khai trên các hàm của Google Cloud.

Triển khai mẫu của Lớp học lập trình

Sao chép các tệp từ codelab-start vào thư mục của dự án.

$ firebase deploy

Sau khi Firebase hoàn tất việc triển khai, bạn sẽ thấy ứng dụng Codelab:

e84c1049eb4cca92.png

Để bắt đầu quy trình uỷ quyền, bạn cần có thông tin đăng nhập của đối tác. Chúng tôi sẽ trình bày thông tin này trong phần tiếp theo.

5. Xử lý OAuth

OAuth là tiêu chuẩn web để uỷ quyền truy cập, thường được người dùng sử dụng để cấp cho các ứng dụng bên thứ ba quyền truy cập vào thông tin tài khoản của họ mà không cần chia sẻ mật khẩu. Chúng tôi sử dụng OAuth 2.0 để cho phép nhà phát triển truy cập vào thiết bị của người dùng thông qua Quyền sử dụng thiết bị.

7ee31f5d9c37f699.png

Chỉ định URI chuyển hướng

Bước đầu tiên của quy trình OAuth là truyền một nhóm tham số đến điểm cuối OAuth 2.0 của Google. Sau khi nhận được sự đồng ý của người dùng, các máy chủ OAuth của Google sẽ gửi một yêu cầu kèm theo mã uỷ quyền đến URI chuyển hướng của bạn.

Cập nhật hằng số SERVER_URI (dòng 19) bằng URL lưu trữ của riêng bạn trong scripts.js:

const SERVER_URI = "https://[GCP-Project-Id].web.app";

Việc triển khai lại ứng dụng với thay đổi này sẽ cập nhật URI chuyển hướng được dùng cho dự án của bạn.

$ firebase deploy

Bật URI chuyển hướng

Sau khi cập nhật URI chuyển hướng trong tệp tập lệnh, bạn cũng phải thêm URI đó vào danh sách URI chuyển hướng được phép cho Mã ứng dụng mà bạn đã tạo cho dự án của mình. Chuyển đến trang Thông tin đăng nhập trong Google Cloud Platform. Trang này sẽ liệt kê tất cả thông tin đăng nhập được tạo cho dự án của bạn:

1a07b624b5e548da.png

Trong danh sách Mã ứng dụng OAuth 2.0, hãy chọn Mã ứng dụng mà bạn đã tạo ở bước Tạo dự án. Thêm URI chuyển hướng của ứng dụng vào danh sách URI chuyển hướng được uỷ quyền cho dự án của bạn.

6d65b298e1f005e2.png

Hãy thử đăng nhập!

Truy cập vào URL lưu trữ mà bạn thiết lập bằng Firebase, nhập thông tin đăng nhập của đối tác rồi nhấp vào nút ĐĂNG NHẬP. Mã ứng dụng khách và Mật khẩu ứng dụng khách là thông tin đăng nhập mà bạn nhận được từ Google Cloud Platform, còn Mã dự án là thông tin đăng nhập từ Bảng điều khiển quyền sử dụng thiết bị.

78b48906a2dd7c05.png

Nút ĐĂNG NHẬP sẽ đưa người dùng trải qua quy trình OAuth cho doanh nghiệp của bạn, bắt đầu từ màn hình đăng nhập vào Tài khoản Google của họ. Sau khi đăng nhập, người dùng sẽ được yêu cầu cấp quyền cho dự án của bạn để truy cập vào các thiết bị Nest của họ.

e9b7887c4ca420.png

Vì đây là một ứng dụng mô phỏng, nên Google sẽ đưa ra cảnh báo trước khi chuyển hướng!

b227d510cb1df073.png

Nhấp vào "Nâng cao", sau đó chọn "Truy cập web.app (không an toàn)" để hoàn tất việc chuyển hướng đến ứng dụng của bạn.

673a4fd217e24dad.png

Thao tác này sẽ cung cấp Mã OAuth trong yêu cầu GET đến. Sau đó, ứng dụng sẽ trao đổi mã này để lấy Mã truy cập và Mã làm mới.

6. Điều khiển thiết bị

Ứng dụng mẫu Quyền sử dụng thiết bị sử dụng các lệnh gọi API REST Smart Device Management để điều khiển thiết bị Google Nest. Các lệnh gọi này liên quan đến việc truyền mã truy cập trong tiêu đề của yêu cầu GET hoặc POST, cùng với tải trọng cần thiết cho một số lệnh nhất định.

Chúng tôi đã viết một hàm yêu cầu truy cập chung để xử lý các lệnh gọi này. Tuy nhiên, bạn sẽ cần cung cấp điểm cuối chính xác, cũng như đối tượng tải trọng (nếu cần) cho hàm này!

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • method – Loại yêu cầu HTTP (GET hoặc POST)
  • call – Một chuỗi đại diện cho lệnh gọi API của chúng tôi, dùng để định tuyến các phản hồi (listDevices, thermostatMode, temperatureSetpoint)
  • localpath – Điểm cuối mà yêu cầu được gửi đến, chứa Mã dự án và Mã thiết bị (được thêm vào sau https://smartdevicemanagement.googleapis.com/v1)
  • tải trọng (*) – Dữ liệu bổ sung cần thiết cho lệnh gọi API (ví dụ: giá trị bằng số biểu thị nhiệt độ cho một điểm đặt)

Chúng ta sẽ tạo các chế độ điều khiển giao diện người dùng mẫu (List Devices, Set Mode, Set Temp) để điều khiển Nest Thermostat:

86f8a193aa397421.png

Các chế độ điều khiển giao diện người dùng này sẽ gọi các hàm tương ứng (listDevices(), postThermostatMode(), postTemperatureSetpoint()) từ scripts.js. Bạn có thể để trống để triển khai! Mục tiêu là chọn phương thức/đường dẫn chính xác và truyền tải trọng đến hàm deviceAccessRequest(...).

Liệt kê thiết bị

Lệnh gọi Quyền sử dụng thiết bị đơn giản nhất là listDevices. Phương thức này sử dụng yêu cầu GET và không yêu cầu tải trọng. Bạn cần phải cấu trúc điểm cuối bằng cách sử dụng projectId. Hoàn tất hàm listDevices() như sau:

function listDevices() {
  var endpoint = "/enterprises/" + projectId + "/devices";
  deviceAccessRequest('GET', 'listDevices', endpoint);
}

Lưu các thay đổi và triển khai lại dự án Firebase bằng lệnh sau:

$ firebase deploy

Sau khi triển khai phiên bản mới của ứng dụng, hãy thử tải lại trang rồi nhấp vào LIST DEVICES (LIỆT KÊ THIẾT BỊ). Thao tác này sẽ điền sẵn danh sách trong phần Điều khiển thiết bị. Bạn sẽ thấy mã nhận dạng của máy điều nhiệt:

b64a198673ed289f.png

Việc chọn thiết bị trong danh sách sẽ cập nhật trường deviceId trong tệp scripts.js. Đối với 2 chế độ kiểm soát tiếp theo, chúng ta sẽ cần chỉ định deviceId cho thiết bị cụ thể mà chúng ta muốn kiểm soát.

Điều khiển máy điều nhiệt

Có 2 đặc điểm để kiểm soát cơ bản một Nest Thermostat trong Smart Device Management API. ThermostatModeTemperatureSetpoint. ThermostatMode đặt chế độ cho Nest Thermostat thành một trong 4 chế độ có thể có: {Off, Heat, Cool, HeatCool}. Sau đó, chúng ta cần cung cấp chế độ đã chọn trong tải trọng.

Thay thế hàm postThermostatMode() trong scripts.js bằng đoạn mã sau:

function postThermostatMode() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var tempMode = id("tempMode").value;
  var payload = {
    "command": "sdm.devices.commands.ThermostatMode.SetMode",
    "params": {
      "mode": tempMode
    }
  };
  deviceAccessRequest('POST', 'thermostatMode', endpoint, payload);
}

Hàm tiếp theo, postTemperatureSetpoint(), xử lý việc đặt nhiệt độ (theo độ C) cho Nest Thermostat. Có 2 thông số có thể được đặt trong tải trọng, heatCelsiuscoolCelsius, tuỳ thuộc vào chế độ máy điều nhiệt đã chọn.

function postTemperatureSetpoint() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var heatCelsius = parseFloat(id("heatCelsius").value);
  var coolCelsius = parseFloat(id("coolCelsius").value);

  var payload = {
    "command": "",
    "params": {}
  };
  
  if ("HEAT" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetHeat";
    payload.params["heatCelsius"] = heatCelsius;
  }
  else if ("COOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetCool";
    payload.params["coolCelsius"] = coolCelsius;
  }
  else if ("HEATCOOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetRange";
    payload.params["heatCelsius"] = heatCelsius;
    payload.params["coolCelsius"] = coolCelsius;
  } else {
    console.log("Off and Eco mode don't allow this function");
    return;
  }
  deviceAccessRequest('POST', 'temperatureSetpoint', endpoint, payload);
}

7. Máy chủ Node.js (Không bắt buộc)

Xin chúc mừng! Bạn đã tạo một ứng dụng web phía máy khách có thể đưa ra các yêu cầu API Quản lý Smart Device Management từ một trình duyệt. Đối với những người muốn xây dựng ở phía máy chủ, chúng tôi muốn giúp bạn bắt đầu bằng một máy chủ proxy có thể chuyển hướng các yêu cầu của bạn từ trình duyệt.

Đối với máy chủ proxy này, chúng ta sẽ sử dụng các hàm trên đám mây của Firebase, Node.js và Express.

Khởi động Cloud Functions

Mở một cửa sổ dòng lệnh mới, chuyển đến thư mục dự án rồi chạy lệnh sau:

$ firebase init functions

Firebase sẽ hỏi bạn một số câu hỏi để khởi động các hàm trên đám mây:

  1. Bạn muốn dùng ngôn ngữ nào để viết Cloud Functions? – JavaScript
  2. Bạn có muốn dùng ESLint để phát hiện các lỗi có thể xảy ra và thực thi kiểu không? – Không
  3. Bạn có muốn cài đặt các phần phụ thuộc bằng npm ngay bây giờ không? – Có

Thao tác này sẽ khởi tạo một thư mục functions trong dự án của bạn, cũng như cài đặt các phần phụ thuộc cần thiết. Bạn sẽ thấy thư mục dự án của mình có một thư mục functions, với tệp index.js để xác định các hàm trên đám mây, package.json để xác định các chế độ cài đặt và thư mục node_modules để chứa các phần phụ thuộc.

Chúng ta sẽ sử dụng 2 thư viện npm để tạo chức năng phía máy chủ: express và xmlhttprequest. Bạn sẽ cần thêm các mục sau vào danh sách phần phụ thuộc trong tệp package.json:

"xmlhttprequest": "^1.8.0",
"express": "^4.17.0"

Sau đó, việc chạy npm install từ thư mục functions sẽ cài đặt các phần phụ thuộc cho dự án của bạn:

$ npm install

Trong trường hợp npm gặp vấn đề khi tải gói xuống, bạn có thể thử lưu xmlhttprequest và express một cách rõ ràng bằng lệnh sau:

$ npm install express xmlhttprequest --save

Nâng cấp lên gói Blaze

Để dùng lệnh firebase deploy, bạn cần nâng cấp lên gói Blaze và thêm một phương thức thanh toán vào tài khoản của mình. Chuyển đến Tổng quan về dự án > Mức sử dụng và thanh toán rồi nhớ chọn gói Blaze cho dự án của bạn.

c6a5e5a21397bef6.png

Tạo máy chủ Express

Máy chủ Express tuân theo một khung đơn giản để phản hồi các yêu cầu GETPOST đến. Chúng tôi đã tạo một servlet để theo dõi các yêu cầu POST, truyền các yêu cầu đó đến một URL đích được chỉ định trong tải trọng và phản hồi bằng phản hồi nhận được từ quá trình truyền.

Sửa đổi tệp index.js trong thư mục functions để có dạng như sau:

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const functions = require('firebase-functions');
const express = require('express');
const http = require('http');

const app = express();
app.use(express.json());


//***** Device Access - Proxy Server *****//

// Serving Get Requests (Not used) 
app.get('*', (request, response) => {
  response.status(200).send("Hello World!");
});
// Serving Post Requests
app.post('*', (request, response) => {
  
  setTimeout(() => {
    // Read the destination address from payload:
    var destination = request.body.address;
    
    // Create a new proxy post request:
    var xhr = new XMLHttpRequest();
    xhr.open('POST', destination);
    
    // Add original headers to proxy request:
    for (var key in request.headers) {
            var value = request.headers[key];
      xhr.setRequestHeader(key, value);
    }
    
    // Add command/parameters to proxy request:
    var newBody = {};
    newBody.command = request.body.command;
    newBody.params = request.body.params;
    
    // Respond to original request with the response coming
    // back from proxy request (to Device Access Endpoint)
    xhr.onload = function () {
      response.status(200).send(xhr.responseText);
    };
    
    // Send the proxy request!
    xhr.send(JSON.stringify(newBody));
  }, 1000);
});

// Export our app to firebase functions:
exports.app = functions.https.onRequest(app);

Để định tuyến các yêu cầu đến máy chủ của chúng tôi, chúng ta cần điều chỉnh các quy tắc viết lại từ firebase.json như sau:

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
        "source": "/proxy**",
        "function": "app"
      },{
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

Thao tác này sẽ định tuyến các URL bắt đầu bằng /proxy đến máy chủ Express của chúng ta, còn lại sẽ tiếp tục chuyển đến index.html.

Lệnh gọi API proxy

Giờ đây, khi đã chuẩn bị xong máy chủ, hãy xác định một URI proxy trong scripts.js để trình duyệt của chúng ta gửi yêu cầu đến địa chỉ này:

const PROXY_URI = SERVER_URI + "/proxy";

Sau đó, hãy thêm hàm proxyRequestscripts.js, có cùng chữ ký với hàm deviceAccessRequest(...), cho các lệnh gọi Gián tiếp truy cập vào thiết bị.

function proxyRequest(method, call, localpath, payload = null) {
    var xhr = new XMLHttpRequest();
    
    // We are doing our post request to our proxy server:
    xhr.open(method, PROXY_URI);
    xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    xhr.onload = function () {
      // Response is passed to deviceAccessResponse function:
      deviceAccessResponse(call, xhr.response);
    };
    
    // We are passing the device access endpoint in address field of the payload:
    payload.address = "https://smartdevicemanagement.googleapis.com/v1" + localpath;
    if ('POST' === method && payload)
        xhr.send(JSON.stringify(payload));
    else
        xhr.send();
}

Bước cuối cùng là thay thế các lệnh gọi deviceAccessRequest(...) bằng hàm proxyRequest(...), trong các hàm postThermostatMode()postTemperatureSetpoint() trong scripts.js.

Chạy firebase deploy để cập nhật ứng dụng.

$ firebase deploy

Nhờ đó, bạn hiện có một máy chủ proxy Node.js đang chạy bằng Express trên Cloud Functions.

Cấp quyền cho Cloud Functions

Bước cuối cùng là xem xét quyền truy cập cho các hàm trên đám mây và đảm bảo rằng ứng dụng phía máy khách của bạn có thể gọi các hàm đó.

Trên Google Cloud Platform, hãy chuyển đến thẻ Cloud Functions trong trình đơn, sau đó chọn hàm trên đám mây:

461e9bae74227fc1.png

Nhấp vào Quyền, rồi nhấp vào Thêm thành viên. Ghi allUsers vào trường thành viên mới và chọn Cloud Functions > Cloud Functions Invoker làm vai trò. Khi bạn nhấp vào Lưu, một thông báo cảnh báo sẽ xuất hiện:

3adb01644217578c.png

Khi bạn chọn Cho phép truy cập công khai, ứng dụng phía máy khách của bạn sẽ có thể sử dụng hàm đám mây.

Xin chúc mừng! Bạn đã hoàn tất tất cả các bước. Giờ đây, bạn có thể chuyển đến ứng dụng web và dùng thử các chế độ điều khiển thiết bị được định tuyến thông qua máy chủ proxy!

Các bước tiếp theo

Bạn đang tìm cách mở rộng kiến thức chuyên môn về Quyền sử dụng thiết bị? Hãy xem tài liệu về đặc điểm để tìm hiểu thêm về cách điều khiển các thiết bị Nest khác và quy trình chứng nhận để tìm hiểu các bước ra mắt sản phẩm trên toàn thế giới!

Nâng cao kỹ năng của bạn bằng ứng dụng mẫu cho ứng dụng web Quyền sử dụng thiết bị. Trong ứng dụng này, bạn sẽ phát triển dựa trên kinh nghiệm có được từ Lớp học lập trình và triển khai một ứng dụng web hoạt động để điều khiển camera Nest, chuông cửa và máy điều nhiệt.