Hello,
I'm working on a React app that uses Firebase as the backend (we use Firestore as the DB), and am seeking some guidance on how best to implement share functionality for our app.
Context
Our app supports creating spreadsheets (for example, something like Google Sheets) that by default are visible only to the creator.
The Firestore security rules on the collection backing the spreadsheets allows read / write only by the creator of the resource.
Existing security rules for the Spreadsheet collection:
read: current auth user is logged in and matches the one on the resource being requested
write: current auth user is logged in and matches the one on the resource being written to
This works nicely for the private case, where we want to limit viewability to only the creator of the spreadsheet. But we're having a few problems implementing share functionality, detailed below.
Problems
Problem 1 - Supporting Viewers
One of the features we want to support is to provide "public" access to a spreadsheet, in a very similar vein to what Google Docs/Sheets supports. Given a spreadsheet, you can generate a link that allows anyone who has that URL to view that spreadsheet (but not edit it). We'd like this to support users who are not logged in or do not have an account set up with Firebase.
(Hacky) solution
- Create a subcollection within the Spreadsheet collection named "viewers", with the resource id of each viewer document being a user_id (the "viewer").
- Upon trying to access the "public" version of the URL, we add the current user to the viewers subcollection of the spreadsheet being viewed. If the user is not logged in, we create and log-in anonymously using Firebase's anonymous auth, and then try again (so this time they should get added as a viewer properly).
Security rules:
read: current auth user is logged in and matches the one on the resource being requested, OR the current auth user is found in the subcollection "viewers" of the resource
write: current auth user is logged in and matches the one on the resource being written to
This works, but seems a little bit hacky. It also pollutes our Users database with garbage anonymous users. We're trying to see if there's a better way to do this.
Problem 2 - Supporting Editors
Another feature we want, similar to "problem 1" above, is the idea to also support "editors" or "collaborators" on a particular spreadsheet (similar to Google Docs/Sheets collaborative editing). As an owner of the spreadsheet, you can generate a link, whereby any logged in (not anonymous) user who has the link is allowed to edit the document.
No solution?
For this problem, we don't have a good solution here. Ideally, we'd want our security rules to look something like this:
read: current user is logged in OR found in "viewers" OR is an approved "editor"
write: current user is logged in OR is an approved "editor"
However, we're stuck on how to add people as editors, based on only having access to the special link.
Scenario:
- Creator generates a link to the page and sends it to her friends that she wants to collaborate with.
- Friend accesses the URL
- Friend gets added into the "editors" list of the document so that they have write access to it going forward.
We're not sure how to set up the rules properly though to allow this though, since we don't want to open up the write access to the collection to allow
anyone to add themselves as an editor.
We've temporarily gotten around this by just not having the "get collaborative link" and instead explicitly require the creator to set the emails/user_ids of the collaborators, which we store on the spreadsheet document itself and check against that. But that's a subpar experience so we're trying to see if we can get the collaborative link working.
We would appreciate any feedback or advice regarding either of the above problems! Let me know if I can answer any questions or provide more details.