firebase-tools: 8.14.0
Platform: macOS
firebase emulators:start --export-on-exit="./my-local-dump"
Then add a user to the Auth emulator then exit by sending a SIGINT.
firebase emulators:start --import="./my-local-dump"
Checking auth emulator again, we see the user we just created is gone.
See above.
Auth users added via the emulator are saved in the emulator export.
The user is lost, it is not saved in the emulator export.
Noticed this too. I imagine it's in the pipeline for the fine folks at Firebase. Very excited for this awesome feature
EDIT: In fact, I think during the live #AskFirebase @davideast mentioned it's something they're looking into 👍🏽
@bradleymackey @IsaiahByDayah thanks for trying out the Auth emulator right away! Yes this is on the roadmap for sure.
Thank you 👏 Really exciting to see the auth emulator, we were waiting on it to write better integration tests on some of our login flows. And it'll soon make it possible to dev locally without using the deployed environment.
But the lack of export makes it impossible for us to use it at the moment. All of our tests depend on a firestore export (generated from a testing data set) and we need the auth emulator to be in sync with it.
Also, remember that you can create users with email+password / phone using the Node.js Admin SDK with UIDs of your choice, which comes in handy when matching database records in other emulators.
Keeping a setup script should unblock you from testing for now. And stay tuned while we work on import/exports!
It would be great to be able to define it in firebase.json like
{
"emulators": {
"ui": {
"enabled": true,
"host": "localhost",
"port": 4000
},
"auth": {
"data": "./.firebase/auth"
}
}
}
@yuchenshi, when you get the time would you be able to provide an example "setup script" that can use the Admin SDK to create users? Not sure if I'm doing something wrong or if I ran into the bug mentioned here (https://github.com/firebase/firebase-admin-node/issues/1077)
Hey there, I've created b/172261810 to track this feature request internally :)
waiting this to be able to use the auth emulator ! thanks guys
At the moment i wrote a script to setup my user before tests, or I run it after starting the Emulator:
const { auth } = require('./emulator-admin');
(async () => {
await auth.createUser({
uid: 'ID',
email: '[email protected]',
password: 'pwd',
displayName: 'User Name',
});
console.log('User created successfully');
process.exit();
})();
The "emulator-admin" script is a simple setup where I initialize an admin app with references to the emuulator's endpoints
I have the same issue + my firestore data is also not saved/restored
@tudor07 you'll need to export it manually or add "--export-on-exit"
@Gbuomprisco Ok, I fixed firestore data, but users are still not exported
Also, remember that you can create users with email+password / phone using the Node.js Admin SDK with UIDs of your choice, which comes in handy when matching database records in other emulators.
Keeping a setup script should unblock you from testing for now. And stay tuned while we work on import/exports!
Hey @yuchenshi what would be the best way to use a startup script? This method would work for me but I’m just unsure where to apply the setup code.
I’ve tried checking the env variables for if it’s the emulator and setting up there, but this will then get called for every hot reload (which doesn’t seem ideal).
Thanks!
Joe
@tudor07 yes, hence this ticket
@Joebayld You'd want it to be a Node.js script that you run every time you start the Auth Emulator, since Admin privileges are required to create with a fixed UID. For example, firebase emulators:exec 'node ./your-setup-script.js && node ./your-test-script.js'. For interactive development, you can replace node ./your-test-script.js with read (or pause on Windows), and you can add --ui after emulators:exec to start the Emulator UI.
We know this is not ideal and we're committed to add support for import/exports just like the other emulators. Once we have that, the tricks above will only be required for more involved setups that cannot be covered with imports.
At the moment i wrote a script to setup my user before tests, or I run it after starting the Emulator:
const { auth } = require('./emulator-admin'); (async () => { await auth.createUser({ uid: 'ID', email: '[email protected]', password: 'pwd', displayName: 'User Name', }); console.log('User created successfully'); process.exit(); })();The "emulator-admin" script is a simple setup where I initialize an admin app with references to the emuulator's endpoints
Can you give us more clue about the "emulator-admin" script. Im trying to do this this way but the user is created in the actulal firebase project and not in the emulator.
````
const admin = require('firebase-admin')
const serviceAccount = require('./serviceAccount.json')
const adminConfig = {
credential: admin.credential.cert(serviceAccount),
databaseURL: 'http://localhost:9000?ns=my-own-kpis',
}
admin.initializeApp(adminConfig)`
```
@faggv added a gist here https://gist.github.com/Gbuomprisco/a74f1b0e91542eca0fcf4b89edf23823 - hope it helps! :)
🙋♂️ waiting for this as well. Thanks so much for the work you do, Emulator Suite is awesome!
I was able to work around this by setting up a script that recreates users with the same UID. In our app, we have a users collection which stores additional user data.
I modified a onUserWrite trigger we already have to store the user email in the user collection (only when using the emulator).
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const throwsHttpError = require('./throwsHttpError');
exports.onUserWrite = fn.firestore.document('users/{userId}').onWrite(async (change, context) => {
const db = admin.firestore();
const newValue = change.after.data();
try {
// do our regular stuff user data.
/**
* Due to a limitation in firebase auth emulator where users are
* not persisted, we store the users email in the user collection
* to allows us to recreate user accounts when bootstrapping the emulator.
*/
if (process.env.FUNCTIONS_EMULATOR === 'true') {
const user = await admin.auth().getUser(userId);
await userDoc.update({ emulator_user_email: user.email });
}
} catch (ex) {
throwsHttpError('unkown', ex.message);
}
});
Then in a script called setup-emulator.js we do the following:
const admin = require('firebase-admin');
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
admin.initializeApp({ projectId: 'YOUR_PROJECT_ID' });
(async () => {
const auth = admin.auth();
const db = admin.firestore();
const usersSnapshot = await db.collection('users').get();
usersSnapshot.forEach((doc) => {
const data = doc.data();
if (data.emulator_user_email) {
auth.createUser({
uid: doc.id,
email: data.emulator_user_email,
password: '123456',
displayName: data.userName,
});
}
});
// used to keep firebase emulator alive
rl.question('Hit CTRL+C to close' () => {});
})();
This is the command we run to start the emulator:
FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 firebase use default && firebase emulators:exec 'node ./functions/setup-emulator.js' --import=./save-data --export-on-exit --ui
The only caveat is that passwords are always reset.
Most helpful comment
@bradleymackey @IsaiahByDayah thanks for trying out the Auth emulator right away! Yes this is on the roadmap for sure.