Getting a sub-collection by a specific field value in Firestore - javascript

How do I find a subcollection based on a field value? I am currently using this code but it doesnt work:
var user = db()
.collection('myCollection')
.doc()
.collection('private')
.where("nam", "==", this.state.passcode);
What I am trying to achieve is making a custom authentication, so giving a custom username and password to users (in this case just a passcode). So I decided to store those credentials in a separate sub-collection inside a document. How can a user authenticate by comparing the values of username and password with the ones of a sub-collection?
Another question, is sub-collection for credentials a good idea? Will it cost the same to me as if I would store those info in the document?

First of all, what you're doing right now is not secure at all. You should never store user credentials in a database, especially not one that's directly accessible to your web and mobile clients. To do this properly, you should be making use of Firebase Authentication to sign in users. (You tagged this question firebase-authentication, which refers to that product.) In fact, doing security properly is very difficult. Firebase Auth will make sure everything is done correctly.
Secondly, the query you have now will never yield any documents. That's because you're not passing anything to doc(), which means it will return a DocumentReference to a non-existent document with a random ID. If you meant to have some sort of unique identifier for each user, perhaps that's something you would want to pass to doc() so that each user's subcollection would be correctly identified.

Related

React Native / Firebase - Creating unique username

So after a user has presses the register button, I want to send the data to a cloud function called Register().
The data that I send is first name, last name, date of birth etc.
I form the username by lower-casing the first name and last name and then joining them up. I want to check if the username exists, then add a number until unique username created. If the username does not exist (meaning its unique), create user account with email and password and store data in firestore.
I check if username exists by a username collection in Firestore with all taken usernames.
Right now the way I do this is with a while async loop at the client side but I want to move this to cloud functions for more security. I tried using the same method with async while loop but firebase cloud functions does not accept await in loops.
Any ideas on how to do this? Perhaps recursion? Any help would be much appreciated :)

Is there a Client.fetchUser() equivalent in Discord.js?

I was trying to find a way to get a User object from a user's ID alone. Client#fetchUser() seemed to be what I was looking for, referring to this
older question.
However that function is no longer in the Discord.js Client Object Documentation
And I can't seem to find a way of doing what fetchUser() is supposed to do. I need to create User Object from User IDs because I'm retrieving saved user data and need to be able to send messages to the users I'm retrieving from save data.
There are 2 ways to go about doing this:
Getting the user from the client.users.cache collection
const user = client.users.cache.get(UserID)
Fetching the user using the fetch() method in the UserManager of client.users
const user = client.users.fetch(UserID)
It seems they merged the functionality of UserManager#fetch()
into what I was looking for, in which it is described as
Obtains a user from Discord, or the user cache if it's already available.
PARAMETER TYPE OPTIONAL DEFAULT DESCRIPTION
id Snowflake
ID of the user
cache boolean true
Whether to cache the new user object if it isn't already
Returns: Promise<User>
So it'll either grab the user from the cache by ID, or retrieve it from Discord if it's not in the cache. I'm guessing they did this to make this functionality more efficient.

Verifying user log email and password by looping through psql table

I am learning to code and am attempting to build a to do web application in node using Express (I think that's the right wording).
I have a table('users') in postgresql which stores user_id,email and password.
When a user logs in to the website I want to loop through the table and ensure the email exists and it matches the password and then the user can log in and when they're logged in - their unique user_id is assigned and brings up their previous to do lists.. I would like to incorporate knex also if possible.
I am at a loss how to do this and would appreciate any tips/pointing in the right direction.
Thanks
Try something basic first
SELECT
user_id
FROM users
WHERE
email = _your_user_email
AND password = _your_user_password;
If the result you get back contains user_id or whatever you want returned, then the user exists. You can expand on this further by checking for email, and let the user know that the email exists but the password is incorrect, etc. Try the simple method first and see if this meet your need.
First of all, I would recommend you to name your id field for your users table as id.
It is best practice to name id fields as id and reference columns as <tablename>_id
(eg. table clothes.id unique identifier for iter and clothes.user_id – foreign key to table users).
Secondly, it is highly NOT recommended to store your passwords as raw data inside of the database (security reasons).
It is a common practice to keep user passwords as hashed data.
For example, take a look at bcrypt package.
To select users (there is no such thing as "loop" in terms of database, it is called "query") you need to
create a query like
select
id,
email,
<any_other_field_you_need>
from
users
where
email = 'your#email.com'
and password = 'your password hash'
In terms of knex it can be written
knex('users')
.select(['id', 'email', '<any_other_field_you_need>'])
.where('email', 'your#email.com')
.where('password', 'your password hash')
Your query params (email, password) you can get from express body.
Make sure you are using POST HTTP method to send your request and pass your data as a body.
In case you don't know express – it's an npm package.
It helps in the creation of web-services. They have a hello world guide on their
official website. Feel free to check it out. Or just simply google "express tutorial for beginner" there are a lot of great tutorials over the internet about it. It's quite popular.

Firebase: setting additional user properties

I'd like to add a property to a Firebase user object. The user documentation says that I can only store additional properties using the Firebase real time database.
I am unsure on how this can works in practice.
What does the following mean in practice?
You cannot add other properties to the Firebase User object directly;
instead, you can store the additional properties in your Firebase
Realtime Database.
I interpret it as following:
"you cannot modify properties of a FIRUser object but you can combine this with additional objects"
I found the set function documentation which I interpet in this way:
var userRef = ref.child("users");
userRef.set({
newfield: "value"
});
Is this a sensible approach?
You're almost there. In the legacy Firebase documentation, we had a section on storing such additional user data.
The key is to store the additional information under the user's uid:
let newUser = [
"provider": authData.provider,
"displayName": authData.providerData["displayName"] as? NSString as? String
]
// Create a child path with a key set to the uid underneath the "users" node
// This creates a URL path like the following:
// - https://<YOUR-FIREBASE-APP>.firebaseio.com/users/<uid>
ref.childByAppendingPath("users")
.childByAppendingPath(authData.uid).setValue(newUser)
I've added a note that we should add this information in the new documentation too. We just need to find a good spot for it.
According to the Custom Claims documentation,
The Firebase Admin SDK supports defining custom attributes on user accounts. [...] User roles can be defined for the following common cases:
Add an additional identifier on a user. For example, a Firebase user could map to a different UID in another system.
[...] Custom claims payload must not exceed 1000 bytes.
However, do this only for authentication-related user data, not for general profile information, per the Best Practices:
Custom claims are only used to provide access control. They are not designed to store additional data (such as profile and other custom data). While this may seem like a convenient mechanism to do so, it is strongly discouraged as these claims are stored in the ID token and could cause performance issues because all authenticated requests always contain a Firebase ID token corresponding to the signed in user.
Use custom claims to store data for controlling user access only. All other data should be stored separately via the real-time database or other server side storage.

Rally App SDK 2.0: Filtering a store of Users by UserPermissions

I am attempting to build a store that consists of only Users that are not disabled and have editor permissions on the selected Project. However, UserPermissions is an array of UserPermission objects, which makes such a filter rather complex. It seems that a UserPermission can be of the WorkspacePermission or the ProjectPermission type. So, it looks like I would first have to check the type of the UserPermission, and then check whether the _refObjectName contains the name of the selected Project and "Editor," OR, alternatively, delve deeper into the ProjectPermission itself and check the Project's name and the Role for "Editor" separately. I have attempted to use the filterBy function, passing in a function that takes a record and an id, but I am unable to hit the breakpoint I set inside that function, so I have no idea whether it is working. The results displayed in a combobox certainly do not seem to match what I am querying for. Any suggestions?
Edit1: I have tried modifying the query to scope to the particular project name, but I receive this error: "Could not parse: Attribute \"Project\" on type ProjectPermission is not allowed in query expressions." Is there any way to get around this?
Here is the modified query, excluding the actual project name:
https://rally1.rallydev.com/slm/webservice/x/ProjectPermission.js?pagesize=1&fetch=true&includeSchema=true&includeMeta=true&query=%28%28Role%20=%20Editor%29%20AND%20%28Project.Name%20%3D%20%22{PROJECT NAME HERE}%22%29%29
Edit2: Just thought someone might want to know. I received this error when trying to add another parameter to the query to filter by a User's DisplayName.
"Could not parse: UserPermission does not support complex queries yet. You can only query by Role OR by User, not both."
Edit3: I am having additional trouble with a call to get all the Project Permissions for a User based on their DisplayName. The query, as far as I'm concerned, is formatted as it should be. However, only results for some users are returned, and I have no idea why other users aren't included. I have even tried modifying it to query on FirstName, and the permissions for the user are not included in the result set.
https://rally1.rallydev.com/slm/webservice/x/ProjectPermission.js?pagesize=200&fetch=true&includeSchema=true&includeMeta=true&query=%28User.DisplayName%20%3D%20%22{INSERT NAME HERE}%22%29
You can query the Permissions endpoint to make sure that the that permission is for an Editor you can see the json for that request by following this link.
To get the list of Users that are active you query them with disabled = false like this.
Once you have Permission data in memory you can filter out the users do not that have Edit permissions and match them with the list of active users.

Categories

Resources