iam*_*lli 8 firebase typescript google-cloud-firestore
我正在尝试动态地将转换器传递给firebases withConverter。如果您查看 上的文档FirestoreDataConverter,如果将转换器直接传递到 ,则提供的示例可以工作withConverter。
// I have modified Post Class as seen in the docs, with additional types
class Post {
constructor(readonly title: string, readonly author: string) {
this.title = title;
this.author = author;
}
toString(): string {
return `${this.title}, by ${this.author}`;
}
}
type PostConverterType = firebase.firestore.FirestoreDataConverter<Post>;
// Example converter from the docs
const postConverter: PostConverterType = {
toFirestore(post: Post): firebase.firestore.DocumentData {
return { title: post.title, author: post.author };
},
fromFirestore(
snapshot: firebase.firestore.QueryDocumentSnapshot,
options: firebase.firestore.SnapshotOptions
): Post {
const data = snapshot.data(options);
return new Post(data.title, data.author);
},
};
// Example when the converter is passed directly into with conveter
// This works without throwing warning.
const postSnap = await firebase
.firestore()
.collection('posts')
.withConverter(postConverter) // Works like a charm, but not ideal for reuse
.doc()
.get();
const post = postSnap.data();
if (post !== undefined) {
console.log({
title: post.title, // string
toString: post.toString(), // string
});
}
Run Code Online (Sandbox Code Playgroud)
上述方法有效,但在我的情况下不太可重用。我头痛的是如何将转换器作为变量传递到像这样的可重用函数中.withConverter(converterVaribleFromProps)。
例如,如果我添加另一个数据来转换,如作者
// Sample Author Format
class Author {
constructor(readonly name: string, readonly email: string) {
this.name = name;
this.email = email;
}
}
type AuthorConverterType = firebase.firestore.FirestoreDataConverter<Author>;
const authorConverter: AuthorConverterType = {
toFirestore(author: Author): firebase.firestore.DocumentData {
return { title: author.name, author: author.email };
},
fromFirestore(
snapshot: firebase.firestore.QueryDocumentSnapshot,
options: firebase.firestore.SnapshotOptions
): Author {
const data = snapshot.data(options);
return new Author(data.title, data.author);
},
};
Run Code Online (Sandbox Code Playgroud)
在这一点上,我有一个Authors只关心 的视图authorConverter和一个Posts针对 的视图postConverter。我创建了一个可重用的函数,它接受集合和转换器并将它们传递给 firebase。对两种视图进行大量重复逻辑。
export const connectToDbFromAnyContext = (
collection: 'posts' | 'users' = 'posts',
converter: PostConverterType | AuthorConverterType // 1. I am stuck here
): (() => void) => {
// Tried to test typeof converter here
// and do conditional checks by in vain
console.log({ 'converterType': typeof converter });
const unsubscribeDb = firebase
.firestore()
.collection(collection)
.withConverter(converter) // 2. Because this complains
.onSnapshot(
(snapshot) => {
const newData = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
}));
// Update state with newTimes
console.log({ newData });
},
(error) => {
console.log({ error });
}
);
// Do some other stuff here
// ...and alot or other repeatitive logic
return unsubscribeDb;
};
Run Code Online (Sandbox Code Playgroud)
正如您在 Comment 中看到的1,我正在尝试使用 Union 类型,converter: PostConverterType | AuthorConverterType但 TSlint 会抛出此错误...2
Argument of type 'PostConverterType | AuthorConverterType' is not assignable to parameter of type 'FirestoreDataConverter<Post>'.
Type 'AuthorConverterType' is not assignable to type 'FirestoreDataConverter<Post>'.
Types of property 'toFirestore' are incompatible.
Type '{ (modelObject: Author): DocumentData; (modelObject: Partial<Author>, options: SetOptions): DocumentData; }' is not assignable to type '{ (modelObject: Post): DocumentData; (modelObject: Partial<Post>, options: SetOptions): DocumentData; }'.
Types of parameters 'modelObject' and 'modelObject' are incompatible.
Type 'Post' is missing the following properties from type 'Author': name, emailts(2345)
Run Code Online (Sandbox Code Playgroud)
请帮忙。谢谢。
| 归档时间: |
|
| 查看次数: |
1827 次 |
| 最近记录: |