FirestoreDataConverter interface

Konwerter używany przez withConverter() do przekształcania obiektów użytkownika typu AppModelType w dane Firestore typu DbModelType.

Za pomocą konwertera możesz określić ogólne argumenty typu podczas przechowywania i pobierania obiektów z Firestore.

W tym kontekście model „AppModel” to klasa używana w aplikacji do łączenia powiązanych informacji i funkcji. Taka klasa może na przykład mieć właściwości ze złożonymi, zagnieżdżonymi typami danych, właściwościami używanymi do notowania, właściwościami typów nieobsługiwanych przez Firestore (takich jak symbol i bigint) oraz funkcjami pomocniczymi, które wykonują operacje złożone. Takie klasy nie są odpowiednie i/lub nie można ich przechowywać w bazie danych Firestore. Wystąpienia takich klas muszą być konwertowane na „zwykłe stare obiekty JavaScript” Cele typu POJO z wyłącznie właściwościami podstawowymi, potencjalnie zagnieżdżone w innych obiektach POJO lub tablicach obiektów POJO. W tym kontekście ten typ jest określany jako „DbModel” i byłby obiektem nadającym się do trwałego przechowywania w Firestore. Dla wygody aplikacje mogą zaimplementować FirestoreDataConverter i zarejestrować konwertera przy użyciu obiektów Firestore, takich jak DocumentReference lub Query, aby automatycznie przekonwertować AppModel na DbModel podczas zapisywania w Firestore oraz przekonwertować DbModel na AppModel podczas pobierania z Firestore.

Podpis:

export declare interface FirestoreDataConverter, DbModelType extends DocumentData = DocumentData> 

Metody

Metoda Opis
fromFirestore(zrzut) Wywoływane przez pakiet SDK Firestore w celu konwertowania danych Firestore na obiekt typu AppModelType. Aby uzyskać dostęp do swoich danych, wywołaj: snapshot.data().Zwykle dane zwracane z usługi snapshot.data() można przesyłać do usługi DbModelType. Nie jest to jednak gwarantowane, ponieważ Firestore nie wymusza schematu w bazie danych. Na przykład zapisy z poprzedniej wersji aplikacji lub zapisy z innego klienta, który nie używały konwertera typów, mogły mieć zapisane dane z innymi właściwościami lub typami właściwości. Implementacja będzie musiała określić, czy w sposób płynny i niezgodny z danymi odzyskasz zgodność z danymi, czy też spowoduje wystąpienie błędu.
toFirestore(modelObject) Wywoływana przez pakiet SDK Firestore w celu przekonwertowania obiektu modelu niestandardowego typu AppModelType na zwykły obiekt JavaScript (odpowiedni do bezpośredniego zapisu w bazie danych Firestore) typu DbModelType. Używana razem z setDoc() i .Typ WithFieldValue rozszerza zakres T, aby umożliwić używanie wartości FieldValue, takich jak deleteField(), jako wartości właściwości.
toFirestore(modelObject; opcje) Wywoływana przez pakiet SDK Firestore w celu przekonwertowania obiektu modelu niestandardowego typu AppModelType na zwykły obiekt JavaScript (odpowiedni do bezpośredniego zapisu w bazie danych Firestore) typu DbModelType. Używana z setDoc() i merge:true lub mergeFields.Typ PartialWithFieldValue rozszerza zakres Partial, aby umożliwić użycie wartości FieldValue, takich jak arrayUnion() jako wartości właściwości. Obsługuje również zagnieżdżone pola Partial, umożliwiając pomijanie zagnieżdżonych pól.

FirestoreDataConverter.fromFirestore()

Wywoływane przez pakiet SDK Firestore w celu konwertowania danych Firestore na obiekt typu AppModelType. Aby uzyskać dostęp do swoich danych, zadzwoń pod numer snapshot.data().

Ogólnie dane zwracane z metody snapshot.data() można rzutować na obiekt DbModelType. Nie jest to jednak gwarantowane, ponieważ Firestore nie wymusza schematu w bazie danych. Na przykład zapisy z poprzedniej wersji aplikacji lub zapisy z innego klienta, który nie używały konwertera typów, mogły mieć zapisane dane z innymi właściwościami lub typami właściwości. Implementacja będzie musiała określić, czy w sposób płynny i niezgodny z danymi odzyskasz zgodność z danymi, czy też spowoduje wystąpienie błędu.

Podpis:

fromFirestore(snapshot: QueryDocumentSnapshot, DocumentData>): AppModelType;

Parametry

Parametr Typ Opis
zrzut QueryDocumentSnapshot<DocumentData, DocumentData> Pole QueryDocumentSnapshot zawierające Twoje dane i metadane.

Zwroty:

Typ modelu aplikacji

FirestoreDataConverter.toFirestore()

Wywoływana przez pakiet SDK Firestore w celu przekonwertowania obiektu modelu niestandardowego typu AppModelType na zwykły obiekt JavaScript (odpowiedni do bezpośredniego zapisu w bazie danych Firestore) typu DbModelType. Używana z setDoc() i .

Typ WithFieldValue rozszerza zakres T, umożliwiając także używanie wartości FieldValue, takich jak deleteField(), jako wartości właściwości.

Podpis:

toFirestore(modelObject: WithFieldValue): WithFieldValue;

Parametry

Parametr Typ Opis
obiekt modelu WithFieldValue

Zwroty:

WithFieldValue

FirestoreDataConverter.toFirestore()

Wywoływana przez pakiet SDK Firestore w celu przekonwertowania obiektu modelu niestandardowego typu AppModelType na zwykły obiekt JavaScript (odpowiedni do bezpośredniego zapisu w bazie danych Firestore) typu DbModelType. Używana z setDoc() i merge:true lub mergeFields.

Typ PartialWithFieldValue rozszerza Partial, aby umożliwić użycie wartości FieldValue, takich jak arrayUnion(), jako wartości właściwości. Obsługuje również zagnieżdżone pola Partial, umożliwiając pomijanie zagnieżdżonych pól.

Podpis:

toFirestore(modelObject: PartialWithFieldValue, options: SetOptions): PartialWithFieldValue;

Parametry

Parametr Typ Opis
obiekt modelu częściowo z wartością pola
opcje SetOptions

Zwroty:

częściowo z wartością pola danych

Przykład

Prosty przykład

const numberConverter = {
    toFirestore(value: WithFieldValue) {
        return { value };
    },
    fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions) {
        return snapshot.data(options).value as number;
    }
};

async function simpleDemo(db: Firestore): Promise {
    const documentRef = doc(db, 'values/value123').withConverter(numberConverter);

    // converters are used with `setDoc`, `addDoc`, and `getDoc`
    await setDoc(documentRef, 42);
    const snapshot1 = await getDoc(documentRef);
    assertEqual(snapshot1.data(), 42);

    // converters are not used when writing data with `updateDoc`
    await updateDoc(documentRef, { value: 999 });
    const snapshot2 = await getDoc(documentRef);
    assertEqual(snapshot2.data(), 999);
}

Przykład zaawansowany

// The Post class is a model that is used by our application.
// This class may have properties and methods that are specific
// to our application execution, which do not need to be persisted
// to Firestore.
class Post {
    constructor(
        readonly title: string,
        readonly author: string,
        readonly lastUpdatedMillis: number
    ) {}
    toString(): string {
        return `${this.title} by ${this.author}`;
    }
}

// The PostDbModel represents how we want our posts to be stored
// in Firestore. This DbModel has different properties (`ttl`,
// `aut`, and `lut`) from the Post class we use in our application.
interface PostDbModel {
    ttl: string;
    aut: { firstName: string; lastName: string };
    lut: Timestamp;
}

// The `PostConverter` implements `FirestoreDataConverter` and specifies
// how the Firestore SDK can convert `Post` objects to `PostDbModel`
// objects and vice versa.
class PostConverter implements FirestoreDataConverter, PostDbModel> {
    toFirestore(post: WithFieldValue): WithFieldValue {
        return {
            ttl: post.title,
            aut: this._autFromAuthor(post.author),
            lut: this._lutFromLastUpdatedMillis(post.lastUpdatedMillis)
        };
    }

    fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): Post {
        const data = snapshot.data(options) as PostDbModel;
        const author = `${data.aut.firstName} ${data.aut.lastName}`;
        return new Post(data.ttl, author, data.lut.toMillis());
    }

    _autFromAuthor(
        author: string | FieldValue
    ): { firstName: string; lastName: string } | FieldValue {
        if (typeof author !== 'string') {
            // `author` is a FieldValue, so just return it.
            return author;
        }
        const [firstName, lastName] = author.split(' ');
        return {firstName, lastName};
    }

    _lutFromLastUpdatedMillis(
        lastUpdatedMillis: number | FieldValue
    ): Timestamp | FieldValue {
        if (typeof lastUpdatedMillis !== 'number') {
            // `lastUpdatedMillis` must be a FieldValue, so just return it.
            return lastUpdatedMillis;
        }
        return Timestamp.fromMillis(lastUpdatedMillis);
    }
}

async function advancedDemo(db: Firestore): Promise {
    // Create a `DocumentReference` with a `FirestoreDataConverter`.
    const documentRef = doc(db, 'posts/post123').withConverter(new PostConverter());

    // The `data` argument specified to `setDoc()` is type checked by the
    // TypeScript compiler to be compatible with `Post`. Since the `data`
    // argument is typed as `WithFieldValue` rather than just `Post`,
    // this allows properties of the `data` argument to also be special
    // Firestore values that perform server-side mutations, such as
    // `arrayRemove()`, `deleteField()`, and `serverTimestamp()`.
    await setDoc(documentRef, {
        title: 'My Life',
        author: 'Foo Bar',
        lastUpdatedMillis: serverTimestamp()
    });

    // The TypeScript compiler will fail to compile if the `data` argument to
    // `setDoc()` is _not_ compatible with `WithFieldValue`. This
    // type checking prevents the caller from specifying objects with incorrect
    // properties or property values.
    // @ts-expect-error "Argument of type { ttl: string; } is not assignable
    // to parameter of type WithFieldValue"
    await setDoc(documentRef, { ttl: 'The Title' });

    // When retrieving a document with `getDoc()` the `DocumentSnapshot`
    // object's `data()` method returns a `Post`, rather than a generic object,
    // which would have been returned if the `DocumentReference` did _not_ have a
    // `FirestoreDataConverter` attached to it.
    const snapshot1: DocumentSnapshot = await getDoc(documentRef);
    const post1: Post = snapshot1.data()!;
    if (post1) {
        assertEqual(post1.title, 'My Life');
        assertEqual(post1.author, 'Foo Bar');
    }

    // The `data` argument specified to `updateDoc()` is type checked by the
    // TypeScript compiler to be compatible with `PostDbModel`. Note that
    // unlike `setDoc()`, whose `data` argument must be compatible with `Post`,
    // the `data` argument to `updateDoc()` must be compatible with
    // `PostDbModel`. Similar to `setDoc()`, since the `data` argument is typed
    // as `WithFieldValue` rather than just `PostDbModel`, this
    // allows properties of the `data` argument to also be those special
    // Firestore values, like `arrayRemove()`, `deleteField()`, and
    // `serverTimestamp()`.
    await updateDoc(documentRef, {
        'aut.firstName': 'NewFirstName',
        lut: serverTimestamp()
    });

    // The TypeScript compiler will fail to compile if the `data` argument to
    // `updateDoc()` is _not_ compatible with `WithFieldValue`.
    // This type checking prevents the caller from specifying objects with
    // incorrect properties or property values.
    // @ts-expect-error "Argument of type { title: string; } is not assignable
    // to parameter of type WithFieldValue"
    await updateDoc(documentRef, { title: 'New Title' });
    const snapshot2: DocumentSnapshot = await getDoc(documentRef);
    const post2: Post = snapshot2.data()!;
    if (post2) {
        assertEqual(post2.title, 'My Life');
        assertEqual(post2.author, 'NewFirstName Bar');
    }
}