FirestoreDataConverter interface

AppModelType türündeki kullanıcı nesnelerini DbModelType türündeki Firestore verilerine dönüştürmek için withConverter() tarafından kullanılan dönüştürücü.

Dönüştürücüyü kullanmak, Firestore'dan nesneleri saklarken ve alırken genel tür bağımsız değişkenleri belirtmenize olanak tanır.

Bu bağlamda, bir "AppModel" Bir uygulamada ilgili bilgileri ve işlevleri bir arada sunmak için kullanılan sınıftır. Bu tür bir sınıf, örneğin karmaşık, iç içe geçmiş veri türlerine, notlandırma için kullanılan özelliklere, Firestore tarafından desteklenmeyen türlerin özelliklerine (symbol ve bigint gibi) ve bileşik işlemler gerçekleştiren yardımcı işlevlere sahip olabilir. Bu tür sınıflar, bir Firestore veritabanında depolanmaya uygun değildir ve/veya mümkün değildir. Bunun yerine, bu tür sınıfların örneklerinin "düz eski JavaScript nesnelerine" dönüştürülmesi gerekir (POJO'lar) yalnızca temel özelliklere sahip, potansiyel olarak diğer POJO'ların veya POJO dizilerinin içine yerleştirilmiş olabilir. Bu bağlamda, bu tür "DbModel" olarak adlandırılır. ve Firestore'da kalmaya uygun bir nesne olacaktır. Kolaylık sağlaması açısından uygulamalar, FirestoreDataConverter öğesini uygulayabilir ve dönüştürücüyü DocumentReference veya Query gibi Firestore nesnelerine kaydederek, Firestore'da depolarken AppModel'yi otomatik olarak DbModel biçimine dönüştürür ve Firestore'dan alırken DbModel öğesini AppModel biçimine dönüştürür.

İmza:

export declare interface FirestoreDataConverter<AppModelType, DbModelType extends DocumentData = DocumentData> 

Yöntemler

Yöntem Açıklama
fromFirestore(anlık görüntü, seçenekler) Firestore verilerini AppModelType türünde bir nesneye dönüştürmek için Firestore SDK'sı tarafından çağrılır. Verilerinize şu numarayı arayarak erişebilirsiniz: snapshot.data(options).Genel olarak, snapshot.data() uygulamasından döndürülen veriler DbModelType öğesine yayınlanabilir; Ancak Firestore, veritabanında bir şema uygulamadığı için bu garanti edilmez. Örneğin, uygulamanın önceki bir sürümünden veya tür dönüştürücüyü kullanmayan başka bir istemciden yapılan yazmalarda, farklı mülklere ve/veya özellik türlerine sahip veriler yazmış olabilir. Uygulamanın, uygun olmayan verileri düzgünce kurtarmasını veya hata bildirmesini seçmesi gerekir.Bu yöntemi geçersiz kılmak için bkz. .
toFirestore(modelObject) AppModelType türündeki bir özel model nesnesini, DbModelType türündeki düz JavaScript nesnesine (doğrudan Firestore veritabanına yazmaya uygun) dönüştürmek için Firestore SDK'sı tarafından çağrılır. set() öğesini merge ve mergeFields ile birlikte kullanmak için toFirestore(), PartialWithFieldValue<AppModelType> ile tanımlanmalıdır.WithFieldValue<T> türü, T değerini genişleterek deleteField() gibi alan değerlerinin özellik değeri olarak da kullanılmasına izin verir.
toFirestore(modelObject, seçenekler) AppModelType türündeki bir özel model nesnesini, DbModelType türündeki düz JavaScript nesnesine (doğrudan Firestore veritabanına yazmaya uygun) dönüştürmek için Firestore SDK'sı tarafından çağrılır. setDoc() ve merge:true veya mergeFields ile kullanılır.PartialWithFieldValue<T> türü, arrayUnion() gibi FieldValue'ların özellik değeri olarak kullanılmasına izin vermek için Partial<T> öğesini genişletir. Ayrıca, iç içe yerleştirilmiş alanların atlanmasına olanak tanıyarak iç içe yerleştirilmiş Partial özelliğini destekler.

FirestoreDataConverter.fromFirestore()

Firestore verilerini AppModelType türünde bir nesneye dönüştürmek için Firestore SDK'sı tarafından çağrılır. Verilerinize şu numarayı arayarak erişebilirsiniz: snapshot.data(options).

Genel olarak, snapshot.data() öğesinden döndürülen veriler DbModelType öğesine yayınlanabilir; Ancak Firestore, veritabanında bir şema uygulamadığı için bu garanti edilmez. Örneğin, uygulamanın önceki bir sürümünden veya tür dönüştürücüyü kullanmayan başka bir istemciden yapılan yazmalarda, farklı mülklere ve/veya özellik türlerine sahip veriler yazmış olabilir. Uygulamanın, uygun olmayan verileri düzgünce kurtarmasını veya hata bildirmesini seçmesi gerekir.

Bu yöntemi geçersiz kılmak için bkz. .

İmza:

fromFirestore(snapshot: QueryDocumentSnapshot<DocumentData, DocumentData>, options?: SnapshotOptions): AppModelType;

Parametreler

Parametre Tür Açıklama
anlık görüntü QueryDocumentSnapshot<DocumentData, DocumentData> Verilerinizi ve meta verilerinizi içeren bir QueryDocumentSnapshot.
seçenekler SnapshotOptions data() ile yapılan ilk aramadan itibaren SnapshotOptions.

Şunu döndürür:

UygulamaModel Türü

FirestoreDataConverter.toFirestore()

AppModelType türündeki bir özel model nesnesini, DbModelType türündeki düz JavaScript nesnesine (doğrudan Firestore veritabanına yazmaya uygun) dönüştürmek için Firestore SDK'sı tarafından çağrılır. set() öğesini merge ve mergeFields ile kullanmak için toFirestore(), PartialWithFieldValue<AppModelType> ile tanımlanmalıdır.

WithFieldValue<T> türü, T değerini genişleterek deleteField() gibi alan değerlerinin de özellik değeri olarak kullanılmasına izin verir.

İmza:

toFirestore(modelObject: WithFieldValue<AppModelType>): WithFieldValue<DbModelType>;

Parametreler

Parametre Tür Açıklama
modelNesnesi WithFieldValue<AppModelType>

Şunu döndürür:

WithFieldValue<DbModelType>

FirestoreDataConverter.toFirestore()

AppModelType türündeki bir özel model nesnesini, DbModelType türündeki düz JavaScript nesnesine (doğrudan Firestore veritabanına yazmaya uygun) dönüştürmek için Firestore SDK'sı tarafından çağrılır. setDoc() ve merge:true veya mergeFields ile kullanılır.

PartialWithFieldValue<T> türü, arrayUnion() gibi FieldValue'ların özellik değerleri olarak kullanılmasına izin vermek için Partial<T> öğesini genişletir. Ayrıca, iç içe yerleştirilmiş alanların atlanmasına olanak tanıyarak iç içe yerleştirilmiş Partial özelliğini destekler.

İmza:

toFirestore(modelObject: PartialWithFieldValue<AppModelType>, options: SetOptions): PartialWithFieldValue<DbModelType>;

Parametreler

Parametre Tür Açıklama
modelNesnesi partWithFieldValue<AppModelType>
seçenekler SetOptions

Şunu döndürür:

KısmenAlanDeğeri<DbModelType>

Örnek

Basit Örnek

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

async function simpleDemo(db: Firestore): Promise<void> {
    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);
}

Gelişmiş Örnek

// 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<Post, PostDbModel> {
    toFirestore(post: WithFieldValue<Post>): WithFieldValue<PostDbModel> {
        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<void> {
    // 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<Post>` 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<Post>`. 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<Post>"
    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<Post> = 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<PostDbModel>` 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<PostDbModel>`.
    // 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<PostDbModel>"
    await updateDoc(documentRef, { title: 'New Title' });
    const snapshot2: DocumentSnapshot<Post> = await getDoc(documentRef);
    const post2: Post = snapshot2.data()!;
    if (post2) {
        assertEqual(post2.title, 'My Life');
        assertEqual(post2.author, 'NewFirstName Bar');
    }
}