Mit Firebase im Cache speichern

Data Studio hat ein eigenes Cachesystem für Berichte. Wenn Sie einen Connector erstellen, können Sie einen benutzerdefinierten Cache implementieren, um Berichte schneller zu erstellen und Ratenlimits für APIs zu vermeiden.

Angenommen, Sie erstellen einen Connector, der historische Wetterdaten für die letzten 7 Tage für eine bestimmte Postleitzahl bereitstellt. Ihr Connector wird immer beliebter, aber die externe API, von der Sie die Daten abrufen, hat strenge Ratenlimits. Die API aktualisiert ihre Daten nur täglich. Für eine bestimmte Postleitzahl ist es also nicht erforderlich, dieselben Daten mehrmals am Tag abzurufen. Mit diesem Lösungsleitfaden können Sie einen täglichen Cache für jede Postleitzahl implementieren.

Voraussetzungen

  • Eine Firebase Realtime Database. Wenn Sie keinen Zugriff darauf haben, erstellen Sie ein Google Cloud Platform-Projekt (GCP) und folgen Sie der Anleitung für den Einstände, um eine eigene Firebase Realtime Database-Instanz zu erstellen.
  • Ein GCP-Dienstkonto zum Lesen und Schreiben von Daten aus der Firebase Realtime Database.
  • Ein Community-Connector, der Daten aus einer Quelle abruft.

Beschränkungen

  • Diese Lösung kann nicht mit [Data Studio Advanced Services] verwendet werden. Wenn Sie Data Studio Advanced Services verwenden, hat Ihr Connector-Code in Apps Script keinen Zugriff auf die Daten. Daher können Sie die Daten nicht mit Apps Script im Cache speichern.
  • Berichtseditoren und ‑betrachter können diesen Cache nicht zurücksetzen.

Lösung

Dienstkonto implementieren

  1. Erstellen Sie ein Dienstkonto in Ihrem Google Cloud-Projekt.
  2. Dieses Dienstkonto muss im Cloud-Projekt Zugriff auf BigQuery haben.
    • Erforderliche IAM-Rollen (Identity and Access Management, Identitäts- und Zugriffsverwaltung): Firebase Admin
  3. Laden Sie die JSON-Datei herunter, um die Schlüssel des Dienstkontos zu erhalten. Speichern Sie den Inhalt der Datei in den Skripteigenschaften Ihres Connector-Projekts. Nach dem Hinzufügen der Schlüssel sollte es in der Apps Script-UI so aussehen:
    Dienstkontoschlüssel in Skripteigenschaften speichern
  4. Fügen Sie Ihrem Apps Script-Projekt die OAuth2 for Apps Script-Bibliothek hinzu.
  5. Implementieren Sie den erforderlichen OAuth2-Code für das Dienstkonto:
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'
    ]);
}

Code zum Lesen und Schreiben in Firebase implementieren

Sie verwenden die Firebase Database REST API, um Daten in einer Firebase Realtime Database zu lesen und zu schreiben. Der folgende Code implementiert die Methoden, die für den Zugriff auf diese API erforderlich sind.

getData() implementieren

Die Struktur für Ihren vorhandenen getData()-Code ohne Caching sollte so aussehen:

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
  };
}

So verwenden Sie Caching in Ihrem getData()-Code:

  1. Bestimmen Sie den „Chunk“ oder die „Einheit“ der Daten, die im Cache gespeichert werden sollen.
  2. Erstellen Sie einen eindeutigen Schlüssel, um die kleinste Dateneinheit im Cache zu speichern.
    Für die Beispielimplementierung wird zipcode aus configparams als Schlüssel verwendet.
    Optional: Für einen Cache pro Nutzer erstellen Sie einen zusammengesetzten Schlüssel mit dem Basisschlüssel und Nutzeridentität. Beispielimplementierung:
    js var baseKey = getBaseKey(request); var userEmail = Session.getEffectiveUser().getEmail(); var hasheduserEmail = getHashedValue(userEmail); var compositeKey = baseKey + hasheduserEmail;

  3. Wenn Daten im Cache vorhanden sind, prüfen Sie, ob der Cache aktuell ist.
    Im Beispiel werden die Daten im Cache für eine bestimmte Postleitzahl mit dem aktuellen Datum gespeichert. Wenn Daten aus dem Cache abgerufen werden, wird das Datum für den Cache mit dem aktuellen Datum verglichen.

    var cacheForZipcode = {
      data: <data being cached>,
      ymd: <current date in YYYYMMDD format>
    }
    
  4. Wenn keine Daten im Cache vorhanden sind oder die Daten im Cache nicht aktuell sind, rufen Sie die Daten aus der Quelle ab und speichern Sie sie im Cache.

Im folgenden Beispiel enthält main.js den getData()-Code mit implementiertem Caching.

Beispielcode

Zusätzliche Ressourcen

Der Chrome UX Connector ermöglicht es Tausenden von Nutzern, ein Dashboard zu verwenden, das auf einer etwa 20 GB großen BigQuery Tabelle basiert. Dieser Connector verwendet die Firebase Realtime Database zusammen mit dem Apps Script Cache Service für einen zweistufigen Caching-Ansatz. Details zur Implementierung finden Sie im Code.