Closed pimlie closed 4 years ago
Hey @pimlie
Thanks for the feature request. You're right, currently this is not possible with the way the module is built.
We could - probably best additionally to the all-in solution - export specific functions that instantiate a service when requested, so one could import that wherever needed and it automatically sets up the service with the provided credentials from nuxt.config.
That would require quite some brain-cells and refactoring I assume, I'll see what I can do, currently bit low on my time budget. So mostly likely won't be today or tomorrow.
Let me know if you already have a plan on how we best could achieve this.
There are multiple options for an API, am currently thinking about using something like this (but still a wip):
export default async (ctx, inject) => {
let firebaseReady = false
let firebase, session
const fire = {
ready: async () => {
if (!firebaseReady) {
firebase = await import('firebase/app')
<% if (typeof options.sessions === 'object') { %>
const { res } = ctx
if (process.server && res && res.locals && res.locals.user) {
const { default: SessionManager } = await import('@nuxtjs/firebase/lib/services/SessionManager')
const manager = new SessionManager(firebase, {
config,
sessions: <%= serialize(options.sessions) %>
})
// Resolve the firebase app corresponding to the server user
session = await manager.startSession(res.locals.user.uid)
res.locals._session = session
res.locals._manager = manager
} else {
session = firebase.apps.find(a => a.name === '[DEFAULT]') || firebase.initializeApp(config)
}
<% } else { %>
if (!firebase.apps.length) {
firebase.initializeApp(config)
}
session = firebase.apps[0]
<% } %>
firebaseReady = true
}
return session
}
}
<% if (options.services.auth) { %>
/** --------------------------------------------------------------------------------------------- **/
/** -------------------------------------- FIREBASE AUTH ---------------------------------------- **/
/** --------------------------------------------------------------------------------------------- **/
let authReady = false
fire.auth = null
// fire.authModule = null
fire.authReady = async () => {
if (!authReady) {
await fire.ready()
await <%= writeImportStatement('realtimeDb') %>
await new Promise(async (resolve) => {
try {
await <%= writeImportStatement('auth') %>
fire.auth = session.auth()
// fire.authModule = firebase.auth
await fire.auth.setPersistence(firebase.auth.Auth.Persistence.SESSION)
const unsubscribe = fire.auth.onAuthStateChanged((user) => {
authReady = true
unsubscribe()
resolve(fire.auth)
})
} catch (err) {
resolve()
}
})
}
return fire.auth
}
<% } %>
ctx.$fire = fire
inject('fire', fire)
Then in my app I can do:
const auth = await ctx.$fire.authReady()
auth.signInWithCustomToken(token)
// or
await ctx.$fire.ready()
await ctx.$fire.authReady()
ctx.$fire.auth.signInWithCustomToken(token)
But still eg thinking about whether I think its a good idea to also keep injecting $fireAuth, it is 'short' but why support two ways of accessing the same object. You can just do ctx.$fire.auth.session
.
Was also thinking about replace ctx.$fire.auth
with the full session
and then adding ready
on the session object, but dont think we should add our own methods to the firebase auth api
edit: updated implementation
Is your feature request related to a problem? Please describe.
At the moment if you use this module all firebase services are included / initiated on every page. I dont want / need this
Describe the solution you'd like
Support delayed loading / initialization of firebase services at the user's request
Describe alternatives you've considered
Do everything manually without this module
Additional context
For example, I only need fireAuth when a user decides to login (am using custom token based login). If a user isn't logged in then I dont need to include fireAuth yet. Some with realtimeDb, I am only using it on a single page