Firebase 使用flatter更新图像时,更新对Cloud Firestore中图像url的所有引用

Firebase 使用flatter更新图像时,更新对Cloud Firestore中图像url的所有引用,firebase,flutter,google-cloud-firestore,firebase-storage,Firebase,Flutter,Google Cloud Firestore,Firebase Storage,在我的Flatter应用程序中,我在CloudFireStore上有一个userData集合,我在其中存储用户的数据,包括姓名、图像url等。。用户可以创建帖子,向帖子添加评论,等等。类似于任何其他社交应用程序,因此我有多个其他集合,其中存储了用户的信息,包括指向其个人资料图像的链接 假设用户在帖子中添加了评论,我将他们的姓名、个人资料图像url和评论文本保存为“postComment”集合中的文档,然后通过阅读此集合和文档在屏幕上显示他/她的个人资料图像、姓名和评论文本 现在,如果用户更新了他

在我的Flatter应用程序中,我在CloudFireStore上有一个userData集合,我在其中存储用户的数据,包括姓名、图像url等。。用户可以创建帖子,向帖子添加评论,等等。类似于任何其他社交应用程序,因此我有多个其他集合,其中存储了用户的信息,包括指向其个人资料图像的链接

假设用户在帖子中添加了评论,我将他们的姓名、个人资料图像url和评论文本保存为“postComment”集合中的文档,然后通过阅读此集合和文档在屏幕上显示他/她的个人资料图像、姓名和评论文本

现在,如果用户更新了他们的配置文件图像,甚至更新了他们的名称,这将反映在userData集合中,那么我需要确保他们的名称和图像url也在所有其他集合中更新

最简单、成本最低的方法是什么?我是否需要遍历所有集合及其文档并更新字段值,或者是否有一个简单的云函数可以处理这个问题

谢谢

我是否需要遍历所有集合及其文档并更新字段值

至少,是的,这是你必须做的

还是有一个简单的云函数可以处理这个问题

当然,您也可以编写自己的云函数来实现这一点。没有一个现有的函数能满足您的需要-您必须对其进行编码

或者,您可以只存储一个文档的URL,将该文档的ID存储在需要引用它的其他文档中,并让客户端使用您需要的URL查询单个文档

我是否需要遍历所有集合及其文档并更新字段值

至少,是的,这是你必须做的

还是有一个简单的云函数可以处理这个问题

当然,您也可以编写自己的云函数来实现这一点。没有一个现有的函数能满足您的需要-您必须对其进行编码


或者,您可以只存储一个文档的URL,将该文档的ID存储在需要引用它的其他文档中,并让客户端使用您需要的URL查询单个文档。

有多种方法可以做到这一点
最好的方法是存储文档引用,而不是一次又一次地存储配置文件图片图像。如果您将图像存储为base64,这也将节省空间损失,并且具有成本效益。

另一种方法效率较低,但您可以将图像存储在firestore中并从那里引用它。
这两个都是参考资料
最后一种可能也是最低效的方法是查询。您可以转到该帖子集合(或者如果您将每个帖子存储为一个集合,则循环浏览所有帖子),然后添加一个where过滤器并搜索imageURL或更安全的唯一ID,然后您可以逐个更改它们
这些是我知道的方法有多种方法
最好的方法是存储文档引用,而不是一次又一次地存储配置文件图片图像。如果您将图像存储为base64,这也将节省空间损失,并且具有成本效益。

另一种方法效率较低,但您可以将图像存储在firestore中并从那里引用它。
这两个都是参考资料
最后一种可能也是最低效的方法是查询。您可以转到该帖子集合(或者如果您将每个帖子存储为一个集合,则循环浏览所有帖子),然后添加一个where过滤器并搜索imageURL或更安全的唯一ID,然后您可以逐个更改它们
这些是我知道的方法

我也在Firestore存储中存储用户配置文件图像,但我使用非常一致的模式使图像易于“猜测”: 当我有一个像“/People/{userID}”这样的文档时,文档中有一个字段“image”,它存储图像的URL。。。 …然后我将它存储在Firestore的路径“People/{userID/image/image.jpg”(例如)中。这样,生成一个StorageRef和一个下载URL就很简单了

它的所有其他用途总是指向现在标准化的URL。更改存储中的图像;所有引用都会更新

对于大多数“用户”应用程序,图像的唯一用途是将其提供给网页,因此只需要URL,其余工作由浏览器完成

正如Fattie更积极地指出的那样,通常您所需要的只是URL。但如果用户更改URL,您仍然需要找到所有引用并更新它们。在Firestore存储中保存副本并使用一致的URL,意味着所有引用都将“更新”只需更改存储在该位置的内容。缺点是在获取时,它将被视为存储读取

我发现在NoSQL中复制数据是非常好的,因为它是静态的——只创建一次,而不是动态更改(这在很多情况下)。如果您的应用程序不适合这种情况,最好存储对真实来源的引用,并承担“查找”的成本

以下是我用来简化此操作的几个实用程序:

export const makeStorageRefFromRecord = (
  record,
  key = null,
  filename = null
) => {
  return FirebaseStorage.ref(
    record.ref.path + (key ? "/" + key : "") + (filename ? "/" + filename : "")
  );
};

export const makeFileURLFromRecord = (record, key = null, filename = null) => {
  return FirebaseStorage.ref(
    record.ref.path + (key ? "/" + key : "") + (filename ? "/" + filename : "")
  ).getDownloadURL();
};
(“键”本质上是字段名)
请记住,refpath是指向记录的由“/”分隔的集合/文档路径组成的字符串,在简单的情况下是完全可以知道的,例如“People/{userID}”。如果保留此内部路径,则可以使用“filename”和“image.jpg”一样简单所以它总是一样的-因为路径的原因,它是唯一的。

我也将用户配置文件图像存储在Firestore存储中,但我使用非常一致的模式使图像易于“猜测”: 当我有一个文档,比如“/People/{userID}”,并且在文档中