Firebase のキャッシュ

Looker Studio には、レポート用の独自のキャッシュ システムがあります。コネクタの作成時にカスタム キャッシュを実装すると、レポートの作成時間を短縮し、API レート制限を回避することができます。

たとえば、郵便番号に基づいて過去 7 日間の気象データを提供するコネクタを開発したとします。コネクタの利用者は拡大していますが、データを取得する外部 API には厳格なレート制限があります。API のデータ更新は 1 日に 1 回のみであるため、同じ郵便番号のデータを 1 日に何度も取得する必要はありません。このソリューション ガイドでは、郵便番号ごとに毎日のキャッシュを実装する方法について説明します。

要件

  • Firebase Realtime Database。このデータベースへのアクセス権限がない場合は、Google Cloud Platform(GCP)プロジェクトを作成し、スタートガイドの手順に沿って、ご自身の Firebase Realtime Database インスタンスを作成してください。
  • Firebase Realtime Database からデータを読み書きするための GCP サービス アカウント。
  • ソースからデータを取得するコミュニティ コネクタ。

制限事項

  • この解決方法は、Looker Studio の Advanced Services には対応していません。Looker Studio の Advanced Services では、Apps Script のコネクタコードはデータにアクセスできないため、Apps Script を使用してデータをキャッシュすることはできません。
  • レポートの編集者と閲覧者は、このキャッシュをリセットすることはできません。

解決方法

サービス アカウントを実装する

  1. Google Cloud プロジェクトでサービス アカウントを作成します。
  2. このサービス アカウントには、Cloud プロジェクトでの BigQuery へのアクセス権限が必要です。
    • 必要な Identity and Access Management(IAM)の役割: Firebase Admin
  3. JSON ファイルをダウンロードして、サービス アカウント キーを取得します。ファイルに含まれるキーを、コネクタ プロジェクトのスクリプト プロパティに保存します。キーを追加すると、次の Apps Script 管理画面のようになります。
    スクリプト プロパティに保存されたサービス アカウントのキー
  4. Apps Script プロジェクトに Apps Script 向け OAuth2 ライブラリを含めます。
  5. サービス アカウントに必要な OAuth2 コードを実装します。
firestore-cache/src/firebase.js
var SERVICE_ACCOUNT_CREDS = 'SERVICE_ACCOUNT_CREDS';
var SERVICE_ACCOUNT_KEY = 'private_key';
var SERVICE_ACCOUNT_EMAIL = 'client_email';
var BILLING_PROJECT_ID = 'project_id';

var scriptProperties = PropertiesService.getScriptProperties();

/**
 * Copy the entire credentials JSON file from creating a service account in GCP.
 * Service account should have `Firebase Admin` IAM role.
 */
function getServiceAccountCreds() {
  return JSON.parse(scriptProperties.getProperty(SERVICE_ACCOUNT_CREDS));
}

function getOauthService() {
  var serviceAccountCreds = getServiceAccountCreds();
  var serviceAccountKey = serviceAccountCreds[SERVICE_ACCOUNT_KEY];
  var serviceAccountEmail = serviceAccountCreds[SERVICE_ACCOUNT_EMAIL];

  return OAuth2.createService('FirebaseCache')
    .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
    .setTokenUrl('https://accounts.google.com/o/oauth2/token')
    .setPrivateKey(serviceAccountKey)
    .setIssuer(serviceAccountEmail)
    .setPropertyStore(scriptProperties)
    .setCache(CacheService.getScriptCache())
    .setScope([
      'https://www.googleapis.com/auth/userinfo.email',
      'https://www.googleapis.com/auth/firebase.database'
    ]);
}

Firebase からデータを読み書きするためのコードを実装する

Firebase Realtime Database からデータを読み書きするには、Firebase Database REST API を使用します。以下のコードで、この API にアクセスするために必要なメソッドを実装します。

getData() を実装する

キャッシュを使用しない既存の getData() コードの構造は、次のようになっています。

firestore-cache/src/without-caching.js
/*
 * This file is only to demonstrate how the `getData()` fucntion would look
 * like without the Firebase Realtime Database caching. It is not a part of
 * the connector code and should not be included in Apps Script / Clasp.
 */

function getData(request) {
  var requestedFields = getFields().forIds(
    request.fields.map(function(field) {
      return field.name;
    })
  );

  var fetchedData = fetchAndParseData(request);
  var data = getFormattedData(fetchedData, requestedFields);

  return {
    schema: requestedFields.build(),
    rows: data
  };
}

getData() コードでキャッシュを使用するには、次の手順を行います。

  1. キャッシュするデータの「チャンク」、すなわち「単位」を決定します。
  2. 最小単位のデータをキャッシュに保存する一意のキーを作成します。
    この実装例では、configparamszipcode をキーとして使用しています。
    (省略可)ユーザーごとにキャッシュを作成する場合は、基本キーとユーザー ID を組み合わせた複合キーを作成します。実装例:
    js var baseKey = getBaseKey(request); var userEmail = Session.getEffectiveUser().getEmail(); var hasheduserEmail = getHashedValue(userEmail); var compositeKey = baseKey + hasheduserEmail;

  3. キャッシュ データがすでに存在する場合は、そのキャッシュが最新であるかどうかが確認されます。
    この例では、指定された郵便番号のキャッシュ データは、そのキャッシュ時の日付で保存されます。キャッシュからデータを取得すると、キャッシュの日付が現在の日付と照合されます。

    var cacheForZipcode = {
      data: <data being cached>,
      ymd: <current date in YYYYMMDD format>
    }
    
  4. キャッシュされたデータが存在しないか、日付が最新でない場合は、ソースからデータが取得され、キャッシュに保存されます。

次の例の main.js には、キャッシュが実装された getData() コードが含まれています。

コード例

補足資料

Chrome UX コネクタは、20 GB 以下の BigQuery テーブルに基づくダッシュボードを、数千人のユーザーに提供しています。このコネクタでは、Firebase Realtime Database と Apps Script キャッシュ サービスを使用する 2 層キャッシュ方式が採用されています。実装方法について詳しくは、コードをご覧ください。