The issue at hand is dealing with user avatars that come from their social media accounts. When a user signs up with our app, the user will use his/her social media account and we simply save the URL to user's avatar in our database.
We're now running into an issue because in a NoSQL database, we're creating many copies of the same data such as user's avatar URL. There's a single source of truth about the user information which is his/her user record in our database. So it's easy enough to update this and detect a change in the avatar URL.
The question is: what is the best way to handle this change in all other places e.g. comments posted by user, etc. This wouldn't be an issue in a relational database scenario but we're using a few NoSQL databases and user avatar URLs are saved in multiple places.
I can think of four ways to handle this and wanted to see how others have handled this scneario:
We save user's avatar URL in all related entities such as comments, etc. When the avatar URL changes, simply use a back-end process to update the URL in all related objects. I think this approach would give the best performance because we use whatever URL comes with the data. No need for any kind of real-time processing. However, this approach can be really costly in terms of maintenance e.g. updating hundreds or even thousands of entities as avatars change.
Another way to handle this is not to save user avatar URL in any of the entities related to the user other than his/her primary record. We then grab the user's avatar URL on first request and cache it, say in Redis cache. As we process requests in the application, we simply pull their avatar URLs from the cache and link to appropriate entities on the fly. I see two major problems with this approach. First, it will create a small delay in managing user requests. For example, if a user requests a video with hundreds of comments under it, I'd have to pull the avatars for all users from my cache and some of them may not even be cached so I'd have to make a database call to get their avatars and cache them for future use. The second issue I see with this is the heavy use of cache, which I'm not against at all but in this scenario, it feels like I'm using the most expensive resource to manage such a trivial requirement.
A third way is to get a user's avatar, say from his/her social login and store the file locally. From that point on, we have full control over that file and its URL will never change unless we change it. Three issues with this approach: the first issue is that I don't think there's a way to download social media profile images as they don't provide a link to a file. Second issue is legality. I'm not sure if we'd have the right to download and store a file that belongs to LinkedIn, Facebook, Google, etc. The third issue is that when the user changes his/her avatar in the social media account, user's avatar in our app won't update automatically. He/She would have to handle that manually. Not the end of the world but not great user experience either.
Use gravatar service. I only know some basic information about this service so I can't say much about it. My primary concerns are that we're using yet another third party resource on top of a third party resource which will only complicate things further. Also, not exactly sure how gravatar works but what if the user doesn't have a gravatar account?
I'd like to see how others handled this scenario. Thanks.
P.S. Based on a few posts I read here and there, I was under the impression that avatar URLs didn't change because social media providers would generate a URL for the user's avatar which is not the file name. So even if the user changes their avatar on their social media account, the URL wouldn't change. I now know as a fact that this assumption is not correct and avatar URL coming from social media providers do change. It's happened to me with LinkedIn. A completely different URL is now my avatar URL. Funny thing is that I have not even updated my profile image with them. Somehow, LinkedIn decided to return a different URL to my profile image.