Firebase auto generated UID changed? - firebase

I am using firebase for login and auth, and was using $createUser. For the first couple weeks working on my app the users I created were being generated with an UID like 'simplelogin:83'. Today, I am working on my app and users are being created with an UID that looks more like a GUID. Did something change on firebases' end? Can I control how that gets generated?

The format has indeed changed from <provider>:<id> into a single opaque UUID. For more information see this post where the change was announced.
There is no way for you to control the format of the user ids for your app. If you're having trouble adapting your code to the new format, reach out to support#firebase.com.

Related

Ionic app how key and value storage works

So I am trying to make a calendar app in ionic and I want to store events, if a user makes one, I looked at the ionic documentation, and it makes it seem too simple I basically copied exactly what they have with a few adjustments and I do not know how to test it. Here is what I have:
save() {
var n = 0
this.event.startTime = new Date(this.readDescription())
this.storage.set('fooditem'+this.increaseVal(),this.event);
this.modalCtrl.dismiss({event: this.event})
}
increaseVal() function just increments the key name so I have a new key for every new value (this is a temporary fix)
I know I probably need to get the data stored after it has been saved but I just need to make sure it actually saves
I'm answering this question with the assumption that you want to know where the data is being stored & to see the value at that location.
Ionic Storage gives options to use SQLite, IndexedDB, WebSQL and localstorage as ways to store data on the device. With the first 3, there is no way to access the data besides fetching it. Local Storage however, is accessible in Chrome Dev Tools > Application > Local Storage
Ionic Storage allows the developer to configure the driver used to store data by specifying it in the driverOrder options in App Module. Simply put localstorage as the first value in this as such driverOrder: ['localstorage', 'indexeddb', 'sqlite', 'websql'] to force the app to store data in localstorage and then you can see the value stored in the location described above.

Avoid linking params during authentication not working in cronofy

I want to create a new account every time user authenticates via cronofy, my link is as below
https://app.cronofy.com/oauth/authorize?
response_type=code&
**avoid_linking=true**&
client_id={clinet_id}&
redirect_uri={redirect_uri}&
scope={scope}
I saw in there documentation for that we need to pass "avoid_linking" params but still every account is created as a profile in previously created account
How to make it work so that every new user is created as a separate account with a new subId
Karl at Cronofy Support here. Once the accounts are linked, we need to unlink them before avoid_linking works as you expect.
Could you please email support#cronofy.com with the email address for the accounts you'd like unlinking, and we will get that sorted for you?
Many thanks
Karl

Request.auth.metadata in security rules?

I have a Firebase project where I'd like for users to be able to see when other users created their profiles. My initial hope was that I could use "user.metadata.creationTime" on the frontend to pass the date into the user's extra info document and verify that it is correct by having "request.resource.data.datecreated == request.auth.metadata.creationTime" as a Database Rule, but it looks like it is not possible according to the documentation.
Is there any way I can verify that the creation date is correct on the backend?
More info edit: Below is the code that is being triggered when a user creates a new account on my profile. The three values are displayed publicly. I'm creating a niche gear for sale page so being able to see when a user first created their account could be helpful when deciding if a seller is sketchy. I don't want someone to be able to make it seem like they have been around for longer than they have been.
db.collection('users').doc(user.uid).set({
username: "Username-156135",
bio: "Add a bio",
created: user.metadata.creationTime
});
Firestore rules:
match /users/{id} {
allow get;
allow create, update: if request.resource.data.username is string &&
request.resource.data.bio is string &&
request.resource.data.created == request.auth.metadata.creationTime;
}
user.metadata.creationTime, according to the API documentation is a string with no documented format. I suggest not using it. In fact, what you're trying to do seems impossible since that value isn't available in the API documentation for request.auth.
What I suggest you do instead is use a Firebase Auth onCreate trigger with Cloud Functions to automatically create that document with the current time as a proper timestamp. Then, in security rules, I wouldn't even give the user the ability to change that field, so you can be sure it was only ever set accurately by the trigger. You might be interested in this solution overall.

Firebase/Google Cloud Storage how to store the image

I have a Firestore that has a User Document. When a User uploads a profile image to the bucket I resize it in the Cloud Function and then save the smaller thumbnail of it. Now I am not sure what the best practice is to receive the Download URL for it, there are 2 possibilities:
In the Cloud Function get a Signed URL and store it in the Users Document or
Get the download url on the frontend with the .getDownloadUrl() method.
The problems I have with either solution is
1: The URL is really big, getting multiple Users on a Page this adds up in more size than the actual rest of the User Document
2: In terms of speed im not sure if its the best to loop through a list of Users to get each's thumbnail download URL, but the advantage is I do not have to deal with normalizing the new Profile Pic URL one every occurrence in the database.
The URL is not that that big. Before trying to optimize, first collect some clear benchmarks that suggest the size of the URL is seriously impacting the performance of the page. Don't optimize this if it doesn't need it. I've never heard of anyone complaining that a download URL is bad for performance.
You don't need to loop over all users. You should arrange to have the UID of the user available at the time of the resize, so you can update the correct user. You can put the UID in the path of the file upload and parse it out, or you can put the UID in object metadata at the time of the upload.
Either approach is valid, though. Pick the one that suits you the best. Generating it on the backend is probably more resilient to errors.
As Doug Stevenson mentioned in his answer, I also think you are trying to optimize something that's not even a performance or storage problem. However, if you still want to optimize the size of your URL, I have two solutions for you.
As we already know, the URL of a picture looks similar to this:
https://firebasestorage.googleapis.com/v0/b/project-id/o/images_folder%2vvTMvCsCRsckpR3R5Qg2s.jpg?alt=media&token=2277f575-8ff7-2211-8262-a28ef679d703
So the first solution would be to shorten the links using a service like tiny.cc. There are also other examples but I think you get the idea. So in case of the URL above, after you shorten it, will look like this:
http:// tiny.cc /2r4ucz
The second solution requires the saving two things in your database. It is not about shorten the link, it's about storing less data. So as you can see, the URL above is combined from a "BASE_URL":
https://firebasestorage.googleapis.com/v0/b/project-id/o/images_folder
Which includes the name of your project and the name of the folder where you store the images. It also contains the name of the image, which in my case is an id that is generated by Firestore and it's by definion unique. And the last part is the token id:
2277f575-8ff7-2211-8262-a28ef679d703
So the second solution would be to store in your database only the id of the image and the token and then reconstruct the entire URL client side. So in the example above the only things that you should store are:
Firestore-root
|
--- users (collection)
|
--- uid (document)
|
--- id: vvTMvCsCRsckpR3R5Qg2s
|
--- token: 2277f575-8ff7-2211-8262-a28ef679d703
|
--- //Other user details
If your user will always have a single picture then you can use instead of that random id, the uid that is coming from the authentication processs:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();

Firebase query with simple login

I am trying to query firebase where I have used simple login to differentiate between users. As such firebase looks like this:
users/simplelogin:*/favouritecolour
favouritecolour looks like {0: blue, 1: red, 2: green}
I want to be able to query for all users with the same favouritecolour and send their profile information back to be displayed on the web page.
users/simplelogin:*/profileinformation
The problem I have is that simple login uses authData.uid for "simplelogin:*" and as such it is different for each user. I want to look through all users. I am not sure how to reference the path to just the favouritecolour for each user, as when querying I don't want to have to search the entire database. I have looked for a wildcard token to use in the path name. I have also looked at relative path definitions, where one may be able to skip over branches in a path. No luck. What code do I need to write to return profileinformation as a snapshot for all profiles matching favouritecolour red?
Thanks for your help.
You need to organize data according to how they are going to be accessed, not according to how "it makes sense" in traditional relational DB. This also includes data duplication and non-normalization.
Take a look at this.
So, you also need to keep something like this:
/favouritecolor/{color}/ --> { user1, user2, user3 }

Resources