简体   繁体   English

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

[英]Updating all the references to an image url in Cloud Firestore when the image is updated using Flutter

In my Flutter app, I have a userData collection on Cloud Firestore where I store user's data including name, image url, etc.. The user can create posts, add comments to post, etc. similar to any other social apps out there and so I have multiple other collections where the user's info is stored including the link to their profile image.在我的 Flutter 应用程序中,我在 Cloud Firestore 上有一个 userData 集合,我在其中存储用户数据,包括姓名、图像 url 等。用户可以创建帖子、向帖子添加评论等,类似于其他任何社交应用程序等等我还有多个其他 collections,其中存储了用户信息,包括指向其个人资料图片的链接。

Let's say if the user adds a comment to a post, I save their name, profile image url and comment text as a document inside "postComment" collection and then I display his/her profile image, name and the comment text on the screen by reading this collection and document.假设如果用户在帖子中添加评论,我将他们的姓名、个人资料图片 url 和评论文本保存为“postComment”集合中的文档,然后我在屏幕上显示他/她的个人资料图片、姓名和评论文本阅读本合集和文档。

Now, if the user updates their profile image or even their name which will be reflected in the userData collection, I need to make sure that their name and image url are updated in all other collections as well.现在,如果用户更新他们的个人资料图片甚至他们的名字,这将反映在 userData 集合中,我需要确保他们的名字和图像 url 在所有其他 collections 中也得到更新。

What's the easiest and least costly way to do that?最简单、成本最低的方法是什么? Do I need to loop through all my collections and their documents and update the field values, or is there like a simple cloud function that can handle this?我是否需要遍历我所有的 collections 及其文档并更新字段值,或者是否有一个简单的云 function 可以处理这个问题?

Thanks!谢谢!

I also store user profile images in Firestore Storage, BUT I use a very consistent schema to make the images easy to "guess": When I have a document such as "/People/{userID}", and within the document is a field "image" which stores the URL to the image... ...then I store it in Firestore at the path "People/{userID/image/image.jpg" (eg).我还将用户配置文件图像存储在 Firestore 存储中,但我使用非常一致的模式使图像易于“猜测”:当我有一个文档,例如“/People/{userID}”,并且文档中有一个字段将 URL 存储到图像的“图像”... ...然后我将它存储在 Firestore 中的路径“People/{userID/image/image.jpg”(例如)。 This way it is trivial to generate a StorageRef to it, and a downloadURL.这样,生成一个 StorageRef一个 downloadURL 就很简单了。

All the other uses of it always are to the now-standardized URL. Change the image in Storage;它的所有其他用途始终是现在标准化的 URL。更改存储中的图像; all references update.所有参考更新。

For most "user" applications, the only use of the image is to feed it to a web-page, so just the URL is needed, and let the browser do the rest of the work.对于大多数“用户”应用程序,图像的唯一用途是将其提供给网页,因此只需要 URL,让浏览器完成 rest 的工作。

As Fattie somewhat more aggressively stated, generally all you need is the URL. But following by itself that means you still would have to find all the references and update them if the user changes the URL. Saving a copy in Firestore Storage, and using that consistent URL , means all references will be "updated" just by changing what is stored at that location.正如 Fattie 更积极地说的那样,通常您需要的是 URL。但是这本身意味着如果用户更改 URL,您仍然必须找到所有参考并更新它们。在 Firestore 存储中保存一个副本,并使用它consistent URL ,意味着所有引用都将通过更改存储在该位置的内容来“更新”。 Disadvantage is it will count as a storage read when fetched.缺点是它在获取时算作存储读取。

I'm finding duplicating data in NoSQL is great when it's fairly static - created once, and not dynamically changed (which is a LOT of cases).我发现 NoSQL 中的重复数据非常好,因为它相当 static - 创建一次,而不是动态更改(这是很多情况)。 If your application doesn't fit that, it's better to store a reference to the source-of-truth, and incur the cost of the "lookup".如果您的应用程序不适合,最好存储对真实来源的引用,并承担“查找”的成本。

Here's a couple utilities I use to make this easier:这是我用来简化此操作的几个实用程序:

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();
};

("key" is essentially the fieldname) remember the refpath is a string of the "/" separated collection/document path to the record, and is completely knowable in a simple situation, such as "People/{userID}". (“key”本质上是字段名)记住 refpath 是记录的“/”分隔的集合/文档路径的字符串,并且在简单情况下是完全可知的,例如“People/{userID}”。 If you keep this internal, you can use "filename" as simple as "image.jpg" so it's always the same - it's unique, because of the path .如果你把它保留在内部,你可以使用像“image.jpg”一样简单的“文件名”,所以它总是一样的——它是独一无二的,因为路径

Do I need to loop through all my collections and their documents and update the field values我是否需要遍历我所有的 collections 及其文档并更新字段值

Minimally, yes, that's what you have to do.至少,是的,这就是你必须做的。

or is there like a simple cloud function that can handle this?还是有一个简单的云 function 可以处理这个问题?

You can certainly write your own Cloud Function to do this as well.您当然也可以编写自己的 Cloud Function 来执行此操作。 There is not an existing function that will just do what you want - you have to code it.没有一个现有的 function 可以做你想做的事——你必须对它进行编码。

Alternatively, you can just store the URL is one document, store the ID of that document in the other documents that need to refer to it, and have the client make an query for the single document with the URL you need.或者,您可以只存储 URL 是一个文档,将该文档的 ID 存储在需要引用它的其他文档中,然后让客户端查询您需要的带有 URL 的单个文档。

There are multiple ways to do that.有多种方法可以做到这一点。
The best way to do that is instead of storing the profile picture image again and again, you can store document references.最好的方法不是一次又一次地存储个人资料图片图像,而是可以存储文档引用。 If you are storing the images as base64, this would also save a lost of space and is cost efficient.如果您将图像存储为 base64,这也可以节省空间并且具有成本效益。

Another way of doing it is less efficient but you can store the image in firestore and refer it from there.另一种方法效率较低,但您可以将图像存储在 firestore 中并从那里引用它。
Both of these are from refereces这两个都来自参考资料
The last way of doing it and probably the most inefficient is by querying.最后一种可能也是最低效的方法是查询。 You can go to that collection of post (Or if you store each post as a collection, loop through all of them) and then add a where filter and search for the imageURL or more safely a unique ID and then you can change them all one by one These are the ways that I know您可以 go 到该帖子集合(或者如果您将每个帖子存储为一个集合,循环遍历所有帖子)然后添加一个 where 过滤器并搜索 imageURL 或更安全地搜索一个唯一 ID,然后您可以将它们全部更改通过一个这些是我知道的方式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 flutter 和 firebase 在 Firestore 中使用 URL 作为字符串在 App 中显示图像 - How to display Image in App with flutter and firebase using URL as String in Firestore Flutter:使用 ImagePickerWeb 将图片上传到 Firestore - Flutter: Upload image to Firestore using ImagePickerWeb Flutter show image with.network url 直接从 Firestore 很慢 - Flutter show image with network url directly form Firestore is very slow 使用 Flutter 更新 Firestore 中的项目 - Updating items in Firestore using Flutter Flutter:将更新值映射到 firestore 中的所有文档 - Flutter: Mapping updated values to all documents in firestore 如果使用 flutter 在云 firestore 中更新数据,是否有一种方法可以自动更新页面中的数据 - Is there a way to automatically update the data in the page if a data is updated in cloud firestore using flutter 如何从 firebase 存储中获取图像 URL 列表并将其上传到云 firestore? - How to get a list of image URL from firebase storage and upload it to cloud firestore? 无法从 Cloud Firestore 数据库下载图像 - Cannot download image from Cloud Firestore database 使用 Cloud Function 将图片 URL 上传到 SFTP 服务器 - Upload image URL to SFTP server using Cloud Function 使用 laravel 将图像上传到 Firestore - Upload image to firestore using laravel
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM