Open11

DataConnectでつまったところ

1amageek1amageek

一度定義したschema.gqlに変更を加えたら、謎のエラーが出てきた。

On Account @table(key): Reference an unknown field: id

DBを全て削除しても消えない。

中間ファイルがあるはずだと思って探してたら

/dataconnect/.dataconnect/schema/main

を発見

.dataconnectを一度削除することでエラーは消えた。
どうやらschema.sqlを保存するタイミングで作られるっぽい。

1amageek1amageek

Firebase Data Connectでエミュレーターを起動しようとしたとき、Postgresのサーバーが干渉した。
エミュレーター起動時にはサーバーを落とす必要がある。

1amageek1amageek

@colを使うとdataTypeを指定してPostgresの型を使うことができる。

type Sample @table {
  startTime: String! @col(name: "start_time", dataType: "TIME")
}

しかし現状はバグる。同じことをしてもしたの方がエラーがでる。

mutation insertConst @auth(level: PUBLIC) {
	sample_insert(data: {
		startTime: "10:00:00"
	})
}

mutation insertVal($startTime: String!) @auth(level: PUBLIC) {
	sample_insert(data: {
		startTime: $startTime
	})
}
1amageek1amageek

Schemaの更新がうまくいかない時は、エミュレーターを停止する。

firebase emulators:start
1amageek1amageek

それでもSchemaの更新がうまくいかない時は.dataconnectを削除してVSCodeを再起動する。
大体これでSchemaは更新される。

それでも問題がある場合はSchemaに問題があるので、PROBLEMSをちゃんと解消する。

1amageek1amageek

Generate SDKはNext.jsと同じ階層に配置しないと機能しない。
ここではhostingがnext.jsのdir

connectorId: "default"
## ## Here's an example of how to add generated SDKs.
## ## You'll need to replace the outputDirs with ones pointing to where you want the generated code in your app.
generate:
  javascriptSdk:
    outputDir: "../../hosting/generated"
    package: "@firebasegen/connector"
    packageJsonDir: "../../hosting"
#   swiftSdk:
#     outputDir: <Path where you want the generated SDK to be written to, relative to this file>
#     package: "firebasegen/default"
#   kotlinSdk:
#     outputDir: <Path where you want the generated SDK to be written to, relative to this file>
#     package: connectors.default

1amageek1amageek

Next.jsのClient ComponetではSDKを使うことができるがSSRではそのまま使えない。

SSRしたいときはFirebase Adminではなく、ブラウザ版のFirebase SDKを再度初期化して使う必要がある。



import { FirebaseError, getApp, initializeApp } from "firebase/app"
import { connectAuthEmulator, indexedDBLocalPersistence, browserLocalPersistence, browserPopupRedirectResolver, initializeAuth, onAuthStateChanged, getRedirectResult, browserSessionPersistence, onIdTokenChanged } from "firebase/auth"
import { getAnalytics, isSupported } from "firebase/analytics"
import { connectFirestoreEmulator, getFirestore } from "firebase/firestore"
import { connectStorageEmulator, getStorage } from "firebase/storage"
import { connectDataConnectEmulator, getDataConnect } from "firebase/data-connect";
import { connectorConfig } from "@firebasegen/connector"

export const getFirebaseApp = () => {
  try {
    const firebaseConfig = JSON.parse(process.env.MY_FIREBASE_CONFIG_WEB!)
    const app = initializeApp(firebaseConfig)
    const auth = initializeAuth(app, {
      persistence: [indexedDBLocalPersistence, browserLocalPersistence],
    });
    connectAuthEmulator(auth, "http://localhost:9099/");
    const db = getFirestore(app);
    connectFirestoreEmulator(db, "localhost", 8080);
    const storage = getStorage(app);
    connectStorageEmulator(storage, "localhost", 9199);
    const dataConnect = getDataConnect(app, connectorConfig);
    connectDataConnectEmulator(dataConnect, "localhost", 9399, false);
    console.log(" 🖥️  RUN Emulator");
    return app
  } catch (error) {
    if ((error as FirebaseError).code != "already-initialized") {
      console.error(error)
    }
    return getApp()
  }
}

export default async function Page({ params: { planID } }: Props) {
  getFirebaseApp()
  const result = await getPlan({ id: planID })
  const plan = result.data.plans[0]
  if (!plan) {
    return notFound()
  }
}
1amageek1amageek

型はGenerateしたSDKに含まれる。

GetPlaceServicesData

  const [services, setServices] = useState<GetPlaceServicesData["placeServices"]>([])
1amageek1amageek

queryで1:Nのリレーションを取得したいときは宣言方法が決まってる。

複数形_on_単数系

query getTransportService($id: String!) @auth(level: PUBLIC) {
  transportServices(where: {
    id: { eq: $id }
  }) {
    id
    account {
      id
      username
    }
    unit {
      id
      unitType
      name
      description      
    }
    name
    description
    isAvailable
    timeTableItems_on_transportService { // 複数形_on_単数系で取得できる。
      id
      line {
        id
        name
      }
      lineItem {
        id
        terminal {
          id
          name
        }
      }
      departureTime
      arrivalTime
      index    
    }
    createdAt
    updatedAt
  }
}
1amageek1amageek
  • ユーザーの入力
  • VSCode Extensionが入力を監視
  • Extensionのコンパイラーがエミュレーターにアクセス
  • エミュレーターで問題を検知
  • VSCode Extensionでキャッチ
  • エラー出力