firebase-module
firebase-module copied to clipboard
[Google Cloud Run] SSR auth and page refresh issue in production
I'm seeing an issue when I'm signed in and refresh the page. Instead of staying signed in, I get redirected to the /signin page due to my middleware not detecting the user being logged in. It's almost as if nuxtServerInit isn't running, but only on refresh. Is that a thing? I have SSR set to true, which should be triggering this on the server side, but perhaps I'm missing something.
The only thing that seems to fix this is setting pwa.workbox.dev to true, but that's probably not a correct fix for production? I would also like to avoid doing a second redirect in beforeMount() if that's possible.
This is the setup I use:
store/index.js
export const actions = {
nuxtServerInit({ dispatch, commit }, { res }) {
if (res && res.locals && res.locals.user) {
const { allClaims: claims, idToken: token, ...authUser } = res.locals.user
commit('user/ON_AUTH_STATE_CHANGED_MUTATION', { authUser, claims, token })
}
},
}
store/user.js
export const getters = {
isAuthenticated(state) {
return state.uid !== null
},
}
export const mutations = {
ON_AUTH_STATE_CHANGED_MUTATION(state, { authUser, claims }) {
if (!authUser) {
state.uid = null
return
}
const { uid } = authUser
state.uid = uid
},
}
And then in my middleware where I redirect to /signin
export default function ({ store, redirect }) {
if (!store.getters['user/isAuthenticated']) {
return redirect('/signin')
}
}
Hey @Flawe I guess I will need to add that to the documentation, changing your workbox settings like so should fix the issue:
dev: process.env.NODE_ENV === 'development',
Let me know if that works for you.
BR, Pascal
Hi @lupas,
Thanks for the reply!
I will try this, but it probably won't do anything if that resolves to false in production?
Basically, if I set dev: true it works as expected, and dev: false breaks it. Any chance something else may affect it, the domain maybe or something like that? I've been changing settings randomly but haven't found anything else that affects its behavior except the dev setting.
@Flawe Have you tried it in production? The issue should not appear in production.
We set pwa.workbox.dev to true in dev because workbox has issues with the HMR module which is used in dev by the dev server but non in production. So the issue should not appear there.
@lupas Yea, it's when deployed on Cloud Run with dev: false where I see this issue.
@Flawe
Hmm... Do you start your production server with nuxt build
& nuxt start
commands or only with nuxt
or nuxt dev
?
@lupas
I'm running nuxt build
and nuxt start
in a docker container
Hey @Flawe
Sorry for the late response - did you find the solution to your problem in the meantime or does the problem still exist?
@lupas No worries! I haven't had much time to dig into it yet I'm afraid, but still same issue. I'll try to test a few things soon.
Just wanted to report I got same issue as above, so am wondering if you ever fixed it @Flawe ? My bug report: https://github.com/nuxt-community/firebase-module/issues/452 although I haven't tested in production because I don't have a server yet for hosting.
@dosstx I haven't yet, but, I'm about to do some work on it again. Hopefully I'll get back to you soon.
@lupas Is this error expected when running locally in dev with pwa.workbox.dev = true?
Error registering workbox: TypeError: Cannot read property 'addEventListener' of undefined
at new Workbox (workbox-window.dev.es5.mjs?ae33:643)
at _callee$ (workbox.js?148b:8)
at tryCatch (runtime.js?96cf:63)
at Generator.invoke [as _invoke] (runtime.js?96cf:293)
at Generator.eval [as next] (runtime.js?96cf:118)
at asyncGeneratorStep (asyncToGenerator.js?c973:3)
at _next (asyncToGenerator.js?c973:25)
Actually you know what, this is caused by this setting:
server: {
port: 3000,
host: '0.0.0.0',
timing: false
}
If I remove the host field so it gets served on localhost it's all working as expected. Any chance this could be causing the original issue too? I need this setting for the Cloud Run deployment.
@Flawe
Can you check in Chrome Dev Tools if the service worker (sw.js) gets properly loaded in your productive app?
Most likely the problem lies not with your code above but with the fact that the service-worker does not get loaded properly. Since you get the error message above (which is not expected) your auth service worker most likely is not running and therefore you don't get the user object.
We might find the solution here https://pwa.nuxtjs.org/workbox , but for now I'm also a bit clueless. Would it be easy for you to build a simple minimal case where this error is happening on https://template.nuxtjs.org/ ?
@lupas You're right, the service worker isn't running.
I tried create a sandbox example but it doesn't work because setting server.host to "0.0.0.0" still serves on localhost instead of a random ip. It seems like that's the root of the problem.
It may be related to https. If I add my local ip as an insecure origin like here, the worker runs, but refreshing the page still logs me out for some reason.
Ok so I think I manage to fix this locally:
- Ignore my previous message, I couldn't get the chrome trust flag to work correctly
- Create a self-signed certificate for the local ip where the app is served when host: "0.0.0.0" is used.
- Point nuxt at the certificate, my server setting now looks like this:
server: {
port: 3000,
host: '0.0.0.0',
timing: false,
https: {
key: fs.readFileSync(path.resolve(__dirname, 'key.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'cert.pem'))
}
},
It works now locally. Service-worker runs, refresh keeps me signed in, etc. I haven't tried deploying it to Cloud Run yet. I worry there may be some funny business with redirection on their end to mess up the origin not matching the SSL certificate.
I was having the same issue locally, for me it was resolved without needing a self-signed certificate by using localhost:3000 in the browser rather than 192.168.0.5:3000 or whatever your local IP is. This thread pointed me in the right direction. Seems like Nuxt PWA doesn't play nicely with local IPs.
@IDLYA-David The ip is needed if you want to test with a different device on the local network, unfortunately.
@Flawe not entirely, you can use ngrok to create an http/https tunnel. It's really simple, just install it globally then use ngrok http <your_local_port e.g. 3000>
.
It'll give you a link that's valid for about an hour and 30 mins and when that expires just run the command again.
@Flawe any solution?. I'm presenting the same problem, local it works but mounted on my digital ocean server the service worker does not work. My ip is without ssl certificate, my domain is without ssl certificate?? thanks
@simeon9696 I try ngrok with only "http" it does not load the service worker and try with "https" and loads the service worker perfectly, that seems to be my problem, I must have my domain configured with https so that the service worker works perfectly, thanks