DataConnectでつまったところ
一度定義したschema.gqlに変更を加えたら、謎のエラーが出てきた。
On Account @table(key): Reference an unknown field: id
DBを全て削除しても消えない。
中間ファイルがあるはずだと思って探してたら
/dataconnect/.dataconnect/schema/main
を発見
.dataconnect
を一度削除することでエラーは消えた。
どうやらschema.sqlを保存するタイミングで作られるっぽい。
Firebase Data Connectでエミュレーターを起動しようとしたとき、Postgresのサーバーが干渉した。
エミュレーター起動時にはサーバーを落とす必要がある。
@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
})
}
Schemaの更新がうまくいかない時は、エミュレーターを停止する。
firebase emulators:start
それでもSchemaの更新がうまくいかない時は.dataconnect
を削除してVSCodeを再起動する。
大体これでSchemaは更新される。
それでも問題がある場合はSchemaに問題があるので、PROBLEMS
をちゃんと解消する。
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
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()
}
}
型はGenerateしたSDKに含まれる。
GetPlaceServicesData
const [services, setServices] = useState<GetPlaceServicesData["placeServices"]>([])
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
}
}
EmulatorではPGLiteが動いている。
ユーザーの入力
- VSCode Extensionが入力を監視
- Extensionのコンパイラーがエミュレーターにアクセス
- エミュレーターで問題を検知
- VSCode Extensionでキャッチ
- エラー出力