I have a custom claim "admin" attached to each user, carrying a boolean.
Now, in my frontend i am trying to generate a list of all admins.
For that i need to access all users who have said custom claim set to "true" and put them in an array, which i can then generate the list from.
The array should just look like the following:
const admins = ref([
{
uid: *uid of admin1*,
name: *name of admin1*,
},
{
uid: *uid of admin2*,
name: *name of admin2*,
},
...
])
So the following problems arise:
How do i access all users with said custom claim set to true, so that i can loop over them and populate my array?
Is this a case for a cloud function, so that it can not be manipulated?
I tried reading this Firebase documentation, however i could not make sense of it.
How do i access all users with said custom claim set to true, so that i can loop over them and populate my array?
There is no direct way to query users based on custom claims.
Is this a case for a cloud function?
Yes, you would have to list all users as in the documentation that you've shared and check for custom claims for each user separately.
It might be best to use a database like Firestore or Realtime Database and maintain a collection of all admins. Make sure this cannot be updated from client side directly using security rules.
Related
The javascript project I'm working on provides a way for users to purchase a "virtual" item, which allows them to access to the information about it. For example, purchasing a recipe.
The way I've structured my database is the following;
Database:
Reference:
Item:
Item Information
Users:
Purchases:
Item
When the customer purchases something, a function runs that copies the order data into the "Users" string, as a purchase. From here, I need a way for the user to be granted access to the "Item" object in the reference section to see the "Item Information", to see the information about what was just purchased.
Is there something similar to a list of authorised users in the security rules that can be dynamically changed to achieve this?
There is nothing built into Firebase Authentication of Firebase Realtime Database (or its security rules) for this, but you can likely build it on top.
If you want to grant the user access to each item that they purchased, you'd have rules that look something like this:
{
"rules": {
"Items": {
"$itemId": {
".read": "root.child('Users').child(auth.uid).child('Purchases').child($itemId).exists()"
}
}
}
}
So the .read rule here checks if the item the user is trying to read also exists under the list or Purchases for that user in the database.
This question already has an answer here:
Firebase security rules to check unique value of a child #AskFirebase
(1 answer)
Closed 2 years ago.
I am using Firebase Web SDK in my project. At the moment I am creating a simple mailing list sign up form. I am trying to check that no duplicate emails get signed up. At the moment, it is possible to do this as firebase creates a message id one level up from the data being stored and I do not know how to validate it.
Here is my code:
db.ref("/signup_emails").push({
name: d.name,
email: d.email
}
Whenever this creates an entry into the database it does so with a message_id. Like so"
signup_emails {
- M1itOVYTq-ySh_49rH3 {
name: "John"
email: "example#example.com"
}
}
How do I validate that the email has only been signed up once?
As you have things structured now, it is not possible with Firebase security rules. If you want to know if there's child node with a specific value, and you don't know its full path, you would have to perform a query to find it. However, security rules don't have the ability to perform a query. You can only reference a node by its fully specified path.
If you want to use security rules to find a piece of data, that data will have to be the name of a node that contains that data. So, the email address, or some form of it, will have to be in the path, not in a value.
Or, you can push the logic into backend code that can perform the check for you.
Is it possible to query the Apollo client cache to get a list of filtered data on the client?
After the client fetches data from the graphql server, the data can be seen as being on the local cache from Apollo dev tools.
How can I get a list of 'Item' types which match a set of 'tags' without making a trip to the server?
type Item {
id: ID
text: String
tags: [String]
}
I would assume this is viable with Apollo-link-state custom resolvers, but so far haven't been able to figure out the strategy for it or find an example anywhere online.
I'm aware that Apollo cache's the data by the queries that have been executed and can access it with the ID and .readFragment, but if the data already exists in the client cache, it should be possible to get a list of data for a certain condition?
Update:
The exact requirement is as follows
Get first 100 results for getItem from the Server
User filters the results by some tags on the client
Show the filtered items from 100 records already fetched
FetchMore records to match the filter criteria from the server to fill up the rest of the page upto 100 items.
Allow pagination based on filter criteria.
As more usage happens, we would have most of the items in cache providing a instant filtering experience for most of the data.
The exact question is can we use .readFragment or .readQuery to access the raw list of records and filter on the fly in the client (if so how/example)? Or is there another way to look at this?
This kind of functionality can be achieved using apollo-link-state.
example - 'internal' query can be forced to be cache-only by fetchPolicy
Also consider simple filtering in component state (or other options - it all depends on (sharing filtered result) requirements.
I have created a chat message functionality. The message stores the userid of sender and receiver. How can I get other details of the user just based on the userid?
Is creating a Meteor method the best way or I have to create publish/subscribe pattern for it.
I want to avoid sending all users data to client side.
I tried creating a meteor method but I don't think its the best approach.
Meteor.methods({
getUserInfoById: function (usrId) {
//console.log("BEGIN");
//console.log(usrId);
var user = Meteor.users.findOne(usrId);
//console.log(user);
//console.log("END");
return user;
}
});
Create a publisher (and also a subscriber) for the data about other users that you want a given user to see. You can restrict the fields returned using the {fields: ...} qualifier in the query.
This is a very common pattern. Using a method for this is an anti-pattern due to the extra round-trip delay for something you're likely to show quite often, i.e. another user's username or avatar.
I want to use AutoForm to create a register form which subsequetnly creates users. Furtehremore, new users should be signed in automatically after registering.
Therefore, I created an AutoForm and supplied a meteormethod called signUp:
Meteor.methods({
signUp: function (doc) {
check(doc, Schema.signUp);
Accounts.createUser({username: doc.username, password: doc.password});
}
});
This works perfect. However, I don't know how I can login users from server side? Is this even possible?
If not, how can I solve this issue? Do I need to include Accounts.createUser({username: doc.username, password: doc.password}); in my Schema custom validation function?
To use aldeed:autoform with any collection, you first need to define schema to that collection because autoform relies on simple-schema attached to that collection. Without schema, the form won't appear and you'll see an uncaught exception thrown by autoform.
So at first, you need to define schema. After that, it's possible to update or insert users into Meteor.users collection. See the official docs for the typical plain-object structure of a users collection entity, at first you may just console.log currently authenticated Meteor.user() to see what required fields it has.
My personal advice would be to not use autoform to mess around with users. It's not very secure and you need to explicitly control what users (or roles) can CRUD your users and what users do not. That's just extra pain to solve, and it may simply negate the convenience of autoform.