Firestore rules and query for document map with email keys to share data with users

我怕爱的太早我们不能终老 提交于 2019-12-01 00:41:33

The basic issue was that I did not know how to properly formulate a valid query. It turns out that you don't need to create a query in one line.

You can use FieldPath to construct your query parameter.

var path = new firebase.firestore.FieldPath('roles', email ,'hasRole');
firebase.firestore().collection('stories').where(path, '==', true)

This solves for the original missing piece.

This is a use case for Control Access with Custom Claims and Security Rules.

The Firebase Admin SDK supports defining custom attributes on user accounts. This provides the ability to implement various access control strategies, including role-based access control, in Firebase apps. These custom attributes can give users different levels of access (roles), which are enforced in an application's security rules.

User roles can be defined for the following common cases:

  • Giving a user administrative privileges to access data and resources.
  • Defining different groups that a user belongs to.
  • Providing multi-level access:
  • Differentiating paid/unpaid subscribers.
  • Differentiating moderators from regular users.
  • Teacher/student application, etc.

You'll need to stand up a node server (skill level low). A script like below works to generate the claims.

var admin = require('firebase-admin');

var serviceAccount = require("./blah-blah-blah.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://my-app.firebaseio.com"
});

admin.auth().setCustomUserClaims("9mB3asdfrw34ersdgtCk1", {admin: true}).then(() => {
    console.log("Custom Claim Added to UID. You can stop this app now.");
});

Then on your client side, do something like:

firebase.auth().onAuthStateChanged(function(user) { if (user) {

    //is email address up to date? //do we really want to modify it or mess w it?
    switch (user.providerData[0].providerId) {
        case 'facebook':
        case 'github':
        case 'google':
        case 'twitter':
            break;
        case 'password':
            // if (!verifiedUser) {
            // }
            break;
    }

    //if admin
    firebase.auth().currentUser.getIdToken().then((idToken) => {
        // Parse the ID token.
        const payload = JSON.parse(window.atob(idToken.split('.')[1]));
        // Confirm the user is an Admin or whatever
        if (!!payload['admin']) {
            switch (thisPage) {
                case "/admin":
                    showAdminStuff();
                    break;
            }
        }
        else {
            if(isAdminPage()){
                document.location.href="/";
            }
        }
    })
    .catch((error) => {
        console.log(error);
    });
}
else {
    //USER IS NOT SIGNED IN

}

});

From what I have gathered, you want to make a story private but shareable with anyone. Your biggest concern is for users who do not have the app but have the share link.

And therefore your biggest problem is that the way firebase works means that you cant limit access to your data without using some sort of login.

If you are ok with requiring new users to login, then your answer should just be Dynamic Links. These links are persistent all the way though installation and login which means that anyone can be given a dynamic link that has story access data attached. You would merely need to add a listener to your app's mainActivity or AppDelegate equivalent to record the dynamic link data and run a specif task after login.

If you wish to stay away from the login completely, then you set up the dynamic link to bypass the login process and direct the new-install-user directly to the story. This second option however, requires a bit more work and is less secure because you will probably be forced to duplicate the story data for open access to anyone with the proper link to the story.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!