I am trying to create a separate datastore for unique usernames and extra profile data such as avatar etc. I have the following schema:
mydatabase : {
users:
I would use the same approach you're using. I agree that it makes sense to use the userId as the key instead of a pushId since, as you point out, you'll want to query the data later on.
The only potential challenge of using this structure is if you want users to pick a username at the time the user is created, they will not have read access to the database so they won't be able to check if the username is unique. As long as you're ok with creating a user first and then having them choose a username once authenticated, this won't be a problem. If you'd prefer that they choose a username first, then you could use Cloud Functions for Firebase with an HTTP trigger, and pass the username as part of the request. The request would include a query of the given username and the response would return whether the username is available or not. It could look something like this:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.uniqueUsername = functions.https.onRequest((req, res) => {
const username = req.query.username
admin.database().ref('users').orderByChild('username').equalTo(username)once('value').then(snap => {
// if the child exists, then the username is taken
if (snap.exists()) {
res.send('username not available');
} else {
res.send('username available');
}
})
}