New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add firebase authentication emulator to emulator suite #1677
Comments
@vladimirdjurdjevic thanks for raising this! This is on our list of things to do, but we have not yet decided on how much of the auth service to emulate and the best strategy to do it. Certain things (like anonymous auth) are very easy to emulate while others (like SMS authentication) are very hard. But we definitely want to enable the end-to-end use case you mentioned! Question: would you find it useful if there was a library that allowed you to locally mock a Firebase user for use with the emulators? Something like: firebase.auth().setEmulatedUser({
uid: 'abc123',
// ...
}); |
@samtstern Would the call to |
@samtstern That would help some testing scenarios for sure, but still require real instance for development. My idea is to avoid creating multiple firebase projects for different environments, and to be able to develop locally (offline perhaps). Another approach would be to support different environments for services. If we could create different environments for let's say firestore and auth under the same project, it would solve many issues. I know I can create project per environment, but that's a real pain in the ass. Configuring every environment, replicating data, etc. Ideally, I would like to be able to create one firebase project, and if I need dummy data for manual testing, I could just create a staging environment for firestore, and upload data there. |
@noelmansour good question! That wouldn't be too hard to do, we'd probably want two different calls like |
@vladimirdjurdjevic totally agree that a full-featured emulator is best. Could you explain what things you would need from a "real instance for development" that are not solved by being able to set the user locally? |
Really useful, it would help a lot. |
Yes this would be incredibly useful |
I also would like to unit test |
For that kind of unit testing check out the firebase-functions-test
library, which helps you invoke your function handlers with mock data.
…On Sun, Oct 13, 2019, 5:44 AM Daniel K. ***@***.***> wrote:
I also would like to unit test functions.auth.user().onCreate(). I
suppose right now the best workaround is essentially export callback
function passed on onCreate and supply fake user object to it.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1677?email_source=notifications&email_token=ACATB2QYJLX2LNVDTWJV25TQOMJ4VA5CNFSM4I27PTFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBCVQIQ#issuecomment-541415458>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACATB2SO3IR6UB73F4EMZPTQOMJ4VANCNFSM4I27PTFA>
.
|
@samtstern That actually works along with Firestore emulator? Base on this I got the impression it's for a different purposes.
I certainly don't want online mode for unit testing, that would be a slowpoke. And I am not sure if I can access the Firestore emulator by "stubbing". |
@FredyC thanks for pointing out those docs. The words used are confusing because the "modes" are not a switch you can enable, they're just describing strategies you can take. If you were to start up the Firestore emulator alongside your unit tests, your code could definitely connect to it. If you set the |
@samtstern I still have trouble connecting dots and how is all that going to help me to test There seems to be some cryptic method I tried calling When I search through org for that env variable you have mentioned, it's only in three places and none seems to be relevant to auth really. Unless it's hidden by some string concatenation. I've been also browsing through the https://github.com/firebase/functions-samples but I found no examples of unit testing there. Can you please make some sense of this? :) |
I also have another case, somewhat opposite, where the cloud function code is using |
@samtstern Sorry for the delay. When I say real instance, I mean real instance :D Ideally, I just want to swap config in my angular environment file for development, and to keep implementing auth features like my app is talking to real API, but it actually emulator running on my machine, and I can do it offline. Now, I understand challenges with sending SMS for example. It would be silly to expect the emulator to send real SMS to my phone, but you could maybe just print it to console (the content of SMS that would be sent). It's probably more hassle than the value with this. That's why I think that just supporting multiple environments per project could make stuff much better. It takes to much time to replicate configs between multiple projects for different environments. And also managing multiple service accounts for scripts to be able to seed data to different Firestore projects is a pain. That's why I taught that if we had a whole firebase platform emulated, we could use that for every non-production environment, and manage just one real firebase project. But maybe just supporting multiple environments per project is a better solution with an acceptable outcome. |
@FredyC thanks for all your feedback! It's really helpful to us to see how confusing this can be. There are two main things people want to do in their tests related to auth:
I think clearly (2) is the right story but I was trying to get a sense of how many people would be happy with (1) since it's substantially simpler to implement and maintain. |
@samtstern I see. Correct me if I am wrong, but isn't the (1) already solved? I mean in tests I can just call the following and Firestore emulator will recognize me as that user so I can test against security rules. I haven't actually tried that yet, but looks promising so far :) const app = firebase.initializeTestApp({
projectId,
auth: {
uid: 'owner'
}
}) The (2) definitely sounds very useful, but a lot more complex to tackle for sure. Sadly, my insight into the full product is so limited, I cannot really offer any useful ideas here. I think it should be built incrementally. Instead of trying to cover all scenarios at once, build it based on known use cases and adding on the go. In my limited opinion emulating "user database" along with function triggers don't seem that hard to do. |
@FredyC you're right that (1) is solved for use inside test suites. But the other use case is actually connecting your Android/iOS/Web app directly to the emulator for local development. In which case you can't use |
I see. Honestly, it would be kinda superb if |
@vladimirdjurdjevic I am thinking, wouldn't actually work to basically mock out the Of course, then you need some way to authenticate toward the emulator for Firestore (and connect to it). Something like I outlined in previous #1677 (comment). There is an underlying method for generating unsecured tokens: https://github.com/firebase/firebase-js-sdk/blob/master/packages/testing/src/api/index.ts#L64. Not sure if that would work. Of course, mocking 3rd party libraries is not always that easy, but once figured out, it can bring great results. Eventually, it could be extracted to some library to make it generally easier. I am also thinking these signIn methods can throw quite a plethora of error codes which is something proper tests should take care of as well. That's easy to do with mocking as well. |
@samtstern Extending the Inline with the other emulators, I would expect a separate authentication service tier to be launched over HTTP and a client-side config can redirect the existing API surface to utilize. I would much rather have eccentric AuthN cases return errors with the Admin and Client API minimally supporting CRUD for basic users over username/password. Heck, i think even starting with Custom Token support in the Admin and To @FredyC point, the current strategy for integration Auth testing is to conditionally import the Hack the planet! |
Um, I am calling that method inside tests. The trick is that regular Of course, this might be different for testing auth in eg. web app where test runner would share the process with app code. However, with unit testing you don't usually import a whole app into a test. The |
@FredyC Agreed on the documented usages for unit tests. Was really speaking to full-app scenarios where the apis diverge and dynamic imports go off the documented map. I just wanted to give you attribution for |
@samtstern first of all I would ❤️to have this kind of emulation. I would see no. 1 very useful for writing e2e tests. Currently I have to use real instance for authentication while I can use emulator for hosting, rules, firestore and functions. I think it should be possible to use setEmulatedUser to mock user in same way it's done in firebase.initializeTestApp. It's should be possible to submit e.g. custom tokens and other user related data. It should also be possible to get sample credentials which could be used in client app with |
Thank you @vladimirdjurdjevic for bringing up this issue! We were looking for a solution for almost a year already. We would like to see a real emulator for three things:
I hope that you will release something for us soon, it would make your product more valuable! Developer productivity is very important in such services! |
This seems to be a feature on many people's wish list. Firebase auth seems to be the #1 IDaaS right now pricing wise, so it's really a pain that you can't develop locally with it with Cloud Functions. Hope the FB team has updates for us soon! 🙏 Edit: Pinging @mbleigh from @firebase-ops since this thread is buried under issues... |
I also have this error ... function ignored because the auth emulator does not exist or is not running. this is triggered by this code: functions.auth.user().onDelete() any info on this ... |
I agree with your points. One tip that might help you meanwhile:
You can seed and manage users programmatically using firebase admin SDK, e.g. |
Interesting well I don’t use display name , I use custom users displayName for
real-time db
```js
/**
* updates Custom data in the realtime datastore users object, except for the username
* @param data
* @returns {Promise<void>}
*/
export async function updatePersonalData(data) {
const { displayName } = data
try {
await firebase
.database()
.ref("users/" + firebase.auth().currentUser.uid)
.update({
displayName: displayName,
})
userDataStore.update((user) => {
return { ...user, displayName: displayName }
})
} catch (e) {
alert(e.message)
}
}
```
On Fri, 10 Jul 2020 at 10:44, rishisingh-dev ***@***.***> wrote:
Yes, it returns null.
I tried it on cloud (not locally).
[image: Screen Shot 2020-07-10 at 2 43 12 AM]
<https://user-images.githubusercontent.com/56976320/87140958-29f3ac80-c257-11ea-98d3-084fad619de7.png>
My code is here.
console.log(user.uid);
console.log(user.email);
console.log(user.displayName);
});```
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1677 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABU35Q27EMMHYAYU5CNZR3R23PIDANCNFSM4I27PTFA>
.
--
Kind regards
Nikos Katsikanis
|
Yes, my primary goal was updating the database with user information inside Thanks. |
@samtstern I am very happy to see you working on this :) Just started new project with firebase, and dev experience is already much better (with emulator ui and --inspect-functions option). Looking forward to see auth emulator in action :) Great job! |
another of the best thing is that I don't have to open chrome with no security |
Two month later, is it now possible to give a rough estimate? We would like to ship beginning of the next year. We are now faced with the decision if we start to write integration tests against a real project or if we wait a few month for the auth emulator. Could you help us a bit here? Best, Niklas |
Our policy at Firebase is not to give estimates on when something will launch unless we're 100% sure. Right now we're working hard on the Auth emulator but we're not close enough to being done to pick a launch date. It's one of our top priorities, but I think you should not wait for us to start testing your app. Write your tests against prod today, switch them to target the emulator when it's available. |
Alright, thanks @samtstern. That helps! |
Something we'd really like to use an auth emulator for is testing Cloud Functions and Firestore requests that involve Custom Claims on user tokens. We can sort of test custom claims with Firestore in the rules playground in the Firebase Console, but a full-fledged auth emulator would theoretically enable us to do much more in the way of testing when it comes to user tokens. |
To be clear: we're committed to a full-fledged auth emulator that emulates the actual service endpoints (wherever possible). We're no longer considering something lightweight like my earlier comments suggested. |
@samtstern that's great to hear (along with the custom claims, since that's often used with third party integrations). Is there anywhere we can keep up with the progress/ETA? |
@fandy no sorry we don't have anything to share yet... |
Thanks Sam, currently I’m doing all my testing manually because it’s not
worth the effort to write e2e tests without Auth mocks
On Wed, 26 Aug 2020 at 14:32, Sam Stern ***@***.***> wrote:
@fandy <https://github.com/fandy> no sorry we don't have anything to
share yet...
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1677 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABU35UAQDBYEXKKINJSM43SCT6E7ANCNFSM4I27PTFA>
.
--
Kind regards
Nikos Katsikanis
|
To work around this, I experimented with importing @firebase/testing in the browser. That didn't really work. This, however, does: mangle @firebase/testing source to copy out the following slightly edited chunk:
Now in your app browser-side code, you can import that, and
That works great! Now when I'm running in development, I have a local fake user that the emulator thinks is "testuser" (like the firestore security rules testing guide shows). |
Another workaround that I use is to stub your authentication (I'm using generated fake users for tests). TypeScript example: import type { User as AuthUser } from '@firebase/auth-types'
// not importing a type, but a module of types
import { auth as authTypes} from 'firebase/app'
type Auth = authTypes.Auth
export const authStub = {
getUser(uid: string) {
// for uids like `testuser1234uid`
let n = uid ? uid.replace("testuser", '').replace("uid", '') : ''
return Promise.resolve({
uid,
email: `test.user${n}@foo.com`,
emailVerified: true,
providerData: [{
providerId: 'google.com',
email: `test.user${n}@foo.com`,
uid: `testuser${n}provideruid`,
phoneNumber: null,
displayName: `Test User ${n}`.trim(),
photoURL: 'https://thispersondoesnotexist.com/image',
}],
metadata: {
// https://firebase.google.com/docs/reference/admin/node/admin.auth.UserMetadata
createTime: new Date().toUTCString(),
lastSignInTime: new Date().toUTCString()
},
customClaims: {
username: `testuser${n}`
}
})
},
deleteUser(uid: string) {
return Promise.resolve()
},
async updateUser(uid: string, data: AuthUser) {
let user = await this.getUser(uid)
return { ...user, data }
},
setCustomUserClaims(uid: string, customUserClaims: Object): Promise<void> {
return Promise.resolve()
}
}
export const auth = <Auth><unknown>authStub Also modify your rules as const rules = fs.readFileSync(__dirname + '/src/firebase/firestore/firestore.rules', 'utf8')
const modifiedRules =
rules
.replace(/request\.auth\.token\.email_verified/g, "true")
.replace(/request\.auth\.token\.firebase\.sign_in_provider/g, "'password'")
await firebase.loadFirestoreRules({ projectId, rules: modifiedRules }) It's working great for me. Hope it helps… |
If you're following this thread and willing to be an Alpha tester of the Firebase Authentication Emulator, follow these steps:
Please only do this if you're seriously interested in trying out an early-stage emulator and providing feedback! There will be bugs and some parts of the setup will be hard, but we want to know what you think. |
@samtstern This is great news! I would love to try it, but I am going to production with my current project by the end of the week, so I can't afford to play with it at the moment. Will sign up for alpha as soon as I can :) Thanks for the great work. |
100% will want to try this! your the man Sam! |
@samtstern looking forward to trying it and help whatever I can! |
I need use feature of auth to test functions locally from Android, the context of Auth is always null |
Good news, the Authentication Emulator is part of the fresh 8.14.0 release! 🙌🎊 Thank you for the hard work guys and @samtstern 💪 |
awesome guys! |
I'm just the messenger! The Auth emulator was 99% built by @yuchenshi ... and that's why I'm going to let him have the honor of closing this issue when he wakes up. |
Is there any documentation on this new emulator? (how to install, configure clients, etc) P.S.Thanks a lot for all the hard work on this. This is going enable all sorts of cool stuff for us. |
@nicoburns very soon! Official announcement, docs, and all that good stuff coming very shortly. |
Great news! :) Can't wait to give it a try :) |
I know you've been waiting for this, so let's just cut to the point:
**Shameless plug: I'm also doing a session on "How to set up CI using the Firebase Emulator suite" later today. Locating that on the session schedule is left as an exercise for the reader. P.S. I really cannot take 99% of the credit since the Auth Emulator is of course teamwork. Various people at Firebase and Firebase developers (you) played a big part in this too. Thank you! |
@yuchenshi Is it possible to export created users on exit, just like with firestore emulator? |
@vdjurdjevic not yet, we're working on that. This is a really popular issue and every update notifies 50-100 people. Since we have now released the Auth emulator I am going to lock this issue from future updates. If you have a question, bug, or feature request please start a new issue! |
Is it possible to emulate the authentication API for faster local development and end to end testing? With the Firestore emulator, we don't have to create different projects for different environments (dev, testing, staging, prod), we can just use emulator, seed data to it from JSON files in watch mode for development, or seeding for every test case, etc. To be able to write end to end test that has a user log in, navigation based on role, and then some action, we have to create a separate project to isolate test users, and also seed and clear users there for every test case.
The text was updated successfully, but these errors were encountered: