288 lines
5.9 KiB
Markdown
288 lines
5.9 KiB
Markdown
# SDK Reference
|
|
|
|
## Contents
|
|
- [SDK Generation](#sdk-generation)
|
|
- [Web SDK](#web-sdk)
|
|
- [Android SDK](#android-sdk)
|
|
- [iOS SDK](#ios-sdk)
|
|
- [Admin SDK](#admin-sdk)
|
|
|
|
---
|
|
|
|
## SDK Generation
|
|
|
|
Configure SDK generation in `connector.yaml`:
|
|
|
|
```yaml
|
|
connectorId: my-connector
|
|
generate:
|
|
javascriptSdk:
|
|
outputDir: "../web-app/src/lib/dataconnect"
|
|
package: "@movie-app/dataconnect"
|
|
kotlinSdk:
|
|
outputDir: "../android-app/app/src/main/kotlin/com/example/dataconnect"
|
|
package: "com.example.dataconnect"
|
|
swiftSdk:
|
|
outputDir: "../ios-app/DataConnect"
|
|
```
|
|
|
|
Generate SDKs:
|
|
```bash
|
|
npx -y firebase-tools@latest dataconnect:sdk:generate
|
|
```
|
|
|
|
---
|
|
|
|
## Web SDK
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
npm install firebase
|
|
```
|
|
|
|
### Initialization
|
|
|
|
```typescript
|
|
import { initializeApp } from 'firebase/app';
|
|
import { getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect';
|
|
import { connectorConfig } from '@movie-app/dataconnect';
|
|
|
|
const app = initializeApp(firebaseConfig);
|
|
const dc = getDataConnect(app, connectorConfig);
|
|
|
|
// For local development
|
|
if (import.meta.env.DEV) {
|
|
connectDataConnectEmulator(dc, 'localhost', 9399);
|
|
}
|
|
```
|
|
|
|
### Calling Operations
|
|
|
|
```typescript
|
|
// Generated SDK provides typed functions
|
|
import { listMovies, createMovie, getMovie } from '@movie-app/dataconnect';
|
|
|
|
// Accessing Nested Fields
|
|
const movie = await getMovie({ id: '...' });
|
|
// Relations are just properties on the object
|
|
const director = movie.data.movie.metadata.director;
|
|
const firstActor = movie.data.movie.actors[0].name;
|
|
|
|
// Query
|
|
const result = await listMovies();
|
|
console.log(result.data.movies);
|
|
|
|
// Query with variables
|
|
const movie = await getMovie({ id: 'uuid-here' });
|
|
|
|
// Mutation
|
|
const newMovie = await createMovie({
|
|
title: 'New Movie',
|
|
genre: 'Action'
|
|
});
|
|
console.log(newMovie.data.movie_insert); // Returns key
|
|
```
|
|
|
|
### Subscriptions
|
|
|
|
```typescript
|
|
import { listMoviesRef, subscribe } from '@movie-app/dataconnect';
|
|
|
|
const unsubscribe = subscribe(listMoviesRef(), {
|
|
onNext: (result) => {
|
|
console.log('Movies updated:', result.data.movies);
|
|
},
|
|
onError: (error) => {
|
|
console.error('Subscription error:', error);
|
|
}
|
|
});
|
|
|
|
// Later: unsubscribe();
|
|
```
|
|
|
|
### With Authentication
|
|
|
|
```typescript
|
|
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
|
|
|
|
const auth = getAuth(app);
|
|
await signInWithEmailAndPassword(auth, email, password);
|
|
|
|
// SDK automatically includes auth token in requests
|
|
const myReviews = await myReviews(); // @auth(level: USER) query from examples.md
|
|
```
|
|
|
|
---
|
|
|
|
## Android SDK
|
|
|
|
### Dependencies (build.gradle.kts)
|
|
|
|
```kotlin
|
|
dependencies {
|
|
implementation(platform("com.google.firebase:firebase-bom:33.0.0"))
|
|
implementation("com.google.firebase:firebase-dataconnect")
|
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.0")
|
|
}
|
|
```
|
|
|
|
### Initialization
|
|
|
|
```kotlin
|
|
import com.google.firebase.Firebase
|
|
import com.google.firebase.dataconnect.dataConnect
|
|
import com.example.dataconnect.MyConnector
|
|
|
|
val connector = MyConnector.instance
|
|
|
|
// For emulator
|
|
connector.dataConnect.useEmulator("10.0.2.2", 9399)
|
|
```
|
|
|
|
### Calling Operations
|
|
|
|
```kotlin
|
|
// Query
|
|
val result = connector.listMovies.execute()
|
|
result.data.movies.forEach { movie ->
|
|
println(movie.title)
|
|
// Access nested fields directly
|
|
println(movie.metadata?.director)
|
|
println(movie.actors.firstOrNull()?.name)
|
|
}
|
|
|
|
// Query with variables
|
|
val movie = connector.getMovie.execute(id = "uuid-here")
|
|
|
|
// Mutation
|
|
val newMovie = connector.createMovie.execute(
|
|
title = "New Movie",
|
|
genre = "Action"
|
|
)
|
|
```
|
|
|
|
### Flow Subscription
|
|
|
|
```kotlin
|
|
connector.listMovies.flow().collect { result ->
|
|
when (result) {
|
|
is DataConnectResult.Success -> updateUI(result.data.movies)
|
|
is DataConnectResult.Error -> showError(result.exception)
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## iOS SDK
|
|
|
|
### Dependencies (Package.swift or SPM)
|
|
|
|
```swift
|
|
dependencies: [
|
|
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", from: "11.0.0")
|
|
]
|
|
// Add FirebaseDataConnect to target dependencies
|
|
```
|
|
|
|
### Initialization
|
|
|
|
```swift
|
|
import FirebaseCore
|
|
import FirebaseDataConnect
|
|
|
|
FirebaseApp.configure()
|
|
let connector = MyConnector.shared
|
|
|
|
// For emulator
|
|
connector.useEmulator(host: "localhost", port: 9399)
|
|
```
|
|
|
|
### Calling Operations
|
|
|
|
```swift
|
|
// Query
|
|
let result = try await connector.listMovies.execute()
|
|
for movie in result.data.movies {
|
|
print(movie.title)
|
|
// Access nested fields directly
|
|
print(movie.metadata?.director ?? "Unknown")
|
|
print(movie.actors.first?.name ?? "No actors")
|
|
}
|
|
|
|
// Query with variables
|
|
let movie = try await connector.getMovie.execute(id: "uuid-here")
|
|
|
|
// Mutation
|
|
let newMovie = try await connector.createMovie.execute(
|
|
title: "New Movie",
|
|
genre: "Action"
|
|
)
|
|
```
|
|
|
|
### Combine Publisher
|
|
|
|
```swift
|
|
connector.listMovies.publisher
|
|
.sink(
|
|
receiveCompletion: { completion in
|
|
if case .failure(let error) = completion {
|
|
print("Error: \(error)")
|
|
}
|
|
},
|
|
receiveValue: { result in
|
|
self.movies = result.data.movies
|
|
}
|
|
)
|
|
.store(in: &cancellables)
|
|
```
|
|
|
|
---
|
|
|
|
|
|
|
|
## Admin SDK
|
|
|
|
Server-side operations with elevated privileges (bypasses @auth):
|
|
|
|
### Node.js
|
|
|
|
```typescript
|
|
import { initializeApp, cert } from 'firebase-admin/app';
|
|
import { getDataConnect } from 'firebase-admin/data-connect';
|
|
|
|
initializeApp({
|
|
credential: cert(serviceAccount)
|
|
});
|
|
|
|
const dc = getDataConnect();
|
|
|
|
// Execute operations (bypasses @auth)
|
|
const result = await dc.executeGraphql({
|
|
query: `query { users { id email } }`,
|
|
operationName: 'ListAllUsers'
|
|
});
|
|
|
|
// Or use generated Admin SDK
|
|
import { listAllUsers } from './admin-connector';
|
|
const users = await listAllUsers();
|
|
```
|
|
|
|
### Generate Admin SDK
|
|
|
|
In `connector.yaml`:
|
|
|
|
```yaml
|
|
generate:
|
|
nodeAdminSdk:
|
|
outputDir: "./admin-sdk"
|
|
package: "@app/admin-dataconnect"
|
|
```
|
|
|
|
Generate:
|
|
```bash
|
|
npx -y firebase-tools@latest dataconnect:sdk:generate
|
|
```
|