外部サービス連携

VisualforceからFirestoreを読み書きする実装手順

Firebase側でFirestoreのデータベースとセキュリティルールを用意し、SalesforceのVisualforce・JavaScriptからドキュメントの登録・取得・検索を行う方法を説明します。

2023.02.22

なぜVisualforceからFirestoreを操作するのか

Salesforceのレコードとは別に、Firebaseのアプリ側だけで使うデータをFirestoreに持たせたい場面があります。FirestoreはFirebase Authenticationと組み合わせて使うことが多く、ログインしたユーザーだけが自分のデータを読み書きできるようにするのが基本の形です。ここではVisualforceページのJavaScriptから、ドキュメントの登録・取得・条件検索を行います。

Firestoreとセキュリティルールを用意する

  1. Firestore Databaseを作成する

    Firebase Consoleの「Firestore Database」から「データベースを作成」を選び、ロケーションを指定します。

  2. セキュリティルールを決める

    作成直後は「テストモード」で始めることができ、既定のルールは一定の期限まですべての読み書きを許可する形です。期限が切れると自動的にすべて拒否に変わります。

  3. ルールを本番向けに書き換える

    期限付きの許可のまま公開しないよう、サインイン済みのユーザーだけに絞るルールへ書き換えます。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Firestoreのルールです。サインイン済みのユーザーだけに読み書きを許可します。

テストモードのallow read, write: if trueは、期限を延長し続けると本番でもそのまま動きます。動く状態と、守られている状態は別です。apiKeyは公開前提の値なので、実際にデータを守っているのはこのルールだけです。request.authを条件に含め、サインインしていない相手には読み書きさせない形にします。

コレクションとドキュメントを作る

  1. コレクションを作る

    コレクションIDにusersを入力します。

  2. ドキュメントを作る

    ドキュメントIDは自動IDのままにします。

  3. フィールドを追加する

    フィールド名name(string)とage(number)を追加して保存します。

Cloud Firestoreのデータ画面。usersに1件だけあり、右にage 10・name 山田
作り終えた直後の画面です。usersの下にドキュメントが1件だけある状態を見てください。
設定値の控え。コレクションID users、ドキュメントID 自動ID、name と age の指定
このとき入力した値の控えです。3つの手順で何を入れるかがまとめて読めます。

VisualforceからFirestoreを操作する

SDKの読み込み方は認証の記事と同じで、firebase-app-compat.js・firebase-auth-compat.jsに加えてfirebase-firestore-compat.jsを静的リソースへ追加します。信頼済みURLには、認証用の2つに加えてhttps://firestore.googleapis.comをconnect-srcで登録します。ルールがrequest.auth != nullを要求するため、Firestoreを呼ぶ前に必ずサインインしておきます。

FirestorePage.page

<apex:page
  sidebar="false"
  showHeader="false"
  standardStylesheets="false"
  applyHtmlTag="false"
  applyBodyTag="false"
  docType="html-5.0"
>
  <html>
    <apex:includeScript value="{!URLFOR($Resource.FirebaseAppCompat)}" />
    <apex:includeScript value="{!URLFOR($Resource.FirebaseAuthCompat)}" />
    <apex:includeScript value="{!URLFOR($Resource.FirebaseFirestoreCompat)}" />
    <body>
      <script>
        const firebaseConfig = {
          apiKey: "AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
          authDomain: "example-project.firebaseapp.com",
          projectId: "example-project",
          storageBucket: "example-project.appspot.com",
          messagingSenderId: "123456394807",
          appId: "1:000000000000:web:xxxxxxxxxxxxxxxx"
        };
        const app = firebase.initializeApp(firebaseConfig);
        const email = "xxxxxxxx@example.com";
        const password = "xxxxxxxx";

        firebase.auth().signInWithEmailAndPassword(email, password)
          .then(() => runFirestore())
          .catch((error) => { console.log(error.code); });

        function runFirestore() {
          const db = firebase.firestore();

          db.collection("users").doc("1234568zc0eVpjawMaB8").get()
            .then((doc) => {
              console.log(doc.exists ? doc.data() : "not found");
            });

          db.collection("users").get()
            .then((query) => {
              const rows = [];
              query.forEach((doc) => { rows.push([doc.id, doc.data()]); });
              console.log(rows);
            });

          db.collection("users").where("age", "==", 10).get()
            .then((query) => {
              query.forEach((doc) => { console.log(doc.id, doc.data()); });
            });

          db.collection("users").add({ name: "本田", age: 20 })
            .then((ref) => { console.log(ref.id); })
            .catch((error) => { console.log(error.code); });
        }
      </script>
    </body>
  </html>
</apex:page>

Visualforceページ全体です。サインイン後にFirestoreへ登録・取得・検索を行います。

動作確認

  1. Visualforceページを開く

    作成したページのURLへアクセスします。

  2. コンソールログを確認する

    取得・検索・追加それぞれの結果がログに出力されることを確認します。

  3. Firebase Consoleでデータを確認する

    「Firestore Database」の「データ」タブで、usersコレクションにドキュメントが増えていることを確認します。

Cloud Firestoreのデータ画面。usersに4件並び、右にage 20・name 本田
追加した後の画面です。usersのドキュメントが増え、右側に本田・20が入っています。
ブラウザのアドレスバー。組織名が黒塗りされ、/apex/ページ名だけが読める
開いたページのURLです。組織のドメインは当時から黒塗りにしてあります。

ここで間違えやすい

間違い何が起きるか
サインインせずにFirestoreを呼ぶルールがrequest.auth != nullなら、読み書きとも権限エラーになります
テストモードの期限を延長し続けて公開するサインインの有無に関係なく誰でも読み書きできる状態が続きます
信頼済みURLにfirestore.googleapis.comを追加し忘れるFirestoreへの通信がブロックされます
ドキュメントIDを決め打ちで書いた後、実際のIDと違うget()の結果がexists: falseになります

確認した環境

  • 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点のhelp.salesforce.comとdeveloper.salesforce.comの公式ドキュメントで、信頼済みURLの扱いを確認しています
  • Firebase側はfirebase.google.comの公式ドキュメントで、セキュリティルールの基本構文とFirestore REST APIのエンドポイントを確認しています

まとめ

  • Firestoreはセキュリティルールで守ります。apiKeyを隠しても意味がありません
  • テストモードの期限付きルールは、本番公開前にrequest.authを条件にしたルールへ書き換えます
  • ドキュメントの取得はget()、コレクション全体はget()の一括取得、条件検索はwhere()、追加はadd()で行います
  • Firestoreへの通信にも信頼済みURLのconnect-srcが要ります。firestore.googleapis.comを登録します
  • サインインしていない状態でFirestoreを呼ぶと、ルール次第で権限エラーになります

Salesforceの導入・運用についてご相談ください

導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。