Firebase auth persistent login in pwa - javascript

I am trying to integrate firebase auth in my nuxt pwa for offline use. But while running the app in offline mode it fails with a failed response from www.googleapis.com/getAccountInfo?key=... and securetoken.googleapis.com/token?key=.....
Isn't it suppose to cache that as well? Or is there any workaround for it.
Config in nuxt.config.js
services: {
auth: {
static:true,
persistence: 'local',
initialize: {
onAuthStateChangedMutation: 'ON_AUTH_STATE_CHANGED_MUTATION'
}
},
firestore: {
static:true
},
},
Updated error screenshot

When loading the page/app:
Firebase restores the authentication state from local persistence.
It then tries to verify that the authenticate state is still valid by calling the server.
If that call succeeds, it updates the local state.
If the call to the server could not be completed, it assumes the local state is still correct, at least until it can verify it.
So the call you're seeing is normal/expected, and should not interfere with the functioning of the application while it's offline.

Related

GraphqlWS setting a cookie before establishing the websocket connection

Upon request I'm working on a scraping application that lightly scrapes a external website that makes use of graphql and the graphql-ws package (so graphql over a websocket). I've never used any sort of graphql before.
The site I'm trying to gain access to makes use of a session cookie to authenticate users. Now I'm trying to simulate this in my NodeJS application. I just can't find a way of setting a cookie for the initial http request for opening the socket. Below is the code I currently have.
Code
import { createClient } from 'graphql-ws';
import WebSocket from 'ws';
const client = createClient({
url: 'wss://target.io/graphql',
webSocketImpl: WebSocket,
on: {
connected: (socket) => {
console.log("Connected!");
},
},
});
(async () => {
// Create subscription
})();
This in itself works fine, as long as I don't need to use any authenticated subscriptions. How can I make it so a session cookie is set before establishing a connection?

firebase app check is not working with web client?

I have followed the official firebase app check installation tutorial:
https://firebase.google.com/docs/app-check/web/recaptcha-enterprise-provider
And I'm only getting errors.
I created and setup firebase project
Added app check library to my app
copy pasted app check initialization for web:
const appCheck = initializeAppCheck(firebaseApp, {
provider: new ReCaptchaEnterpriseProvider(
"my_recaptcha_key_here"
),
isTokenAutoRefreshEnabled: true, // Set to true to allow auto-refresh.
});
Enforced storage, enforced firestore from my console.
According to the tutorial, thats all you need to do.
RESULT:
Can't access anything from firestore, I get:
#firebase/app-check: FirebaseError: AppCheck: ReCAPTCHA error. (appCheck/recaptcha-error).
When uploading to storage, I get:
#firebase/app-check: FirebaseError: AppCheck: Fetch server returned an HTTP error status. HTTP status: 403. (appCheck/fetch-status-error).
Why is this happening, I have done all the steps in the tutorial?
Please make sure that the App URL is added to the reCAPTCHA allowed domains list.

Google Cloud OAuth2 scopes not updating

I have a SPA that's supposed to interact with IoT Core and Cloud Pub/Sub through gapi.
First I used only IoT Core. I added the necessary scope both to the app configuration under APIs & Services / Credentials and my gapi client initialization call documented here.
It worked fine, the OAuth consent screen showed the new scope, IoT Core API calls were working.
Now I want to add Cloud Pub/Sub. Again added the scope to both the app configuration and the gapi initialization call. Here's the argument to gapi.client.init:
{
apiKey: config.firebase.apiKey,
clientId: config.clientId,
discoveryDocs: [
'https://cloudiot.googleapis.com/$discovery/rest?version=v1',
'https://pubsub.googleapis.com/$discovery/rest?version=v1',
],
scope:
'https://www.googleapis.com/auth/pubsub https://www.googleapis.com/auth/cloudiot',
}
Yet, when I make a call to the Pub/Sub API, I get this response:
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
}
Here's what I tried:
log out and then back in
wipe browser cache and cookies
revoke all permissions from the app in Google Accounts
Still no luck. The interesting thing is that although now both scopes are added to the app on the cloud side, after revoking app permissions and logging back in, the consent screen requests permission only for the IoT Core scope. The Pub/Sub scope doesn't show up there.
Any ideas what I'm missing?
Found the problem. The login was initiated by another part of the code that didn't have the Pub/Sub scope added.

Writing data in Service Worker to Cloud Firestore

I'm working on a Firebase project and I want to receive firebase cloud messages (send from a Node.js server) in my service worker in my javascript project. This works fine, but now I want to save some data in my firebase cloud firestore from my service worker after receiving the notification. And there is the problem, I'm running in the error listed below:
Uncaught ReferenceError: XMLHttpRequest is not defined at Ln.<anonymous> (xmlhttp.js:167) at Me (channelrequest.js:512) at Ce (webchannelbase.js:1249) at Kn.xa (webchannelbase.js:1251) at re (run.js:124)
Since a few days I'm trying to find the error, but could not find a solution until now. Therefore I hope that you can help me now. I've tried to save the data in the firebase realtime database which works, but because I need to have offline persistence, I had to switch to cloud firestore which runs in the error above.
Here is the code from my node.js server for sending the notification (userID and registrationToken is defined before):
payload = {
data: {
"title": "This is a Notification",
"body": "This is the body of the notification message."
},
};
options = {
priority: "high",
timeToLive: 7200
};
// send message to the registration token
admin.messaging().sendToDevice(registrationToken, payload, options).then(function(response) {
admin.firestore().collection("Logging").doc(userID).set({active: "true"});
}).catch(function(error) {
console.log("Error sending message:", error);
});
And here is the code for receiving the notification in my firebase-messagins service worker file (userID is defined before):
self.addEventListener('notificationclick', function(event) {
event.notification.close();
const keepAlive = async() => {
firebase.firestore().collection("Logging").doc(userID).update({"open": "true"});
}
event.waitUntil(keepAlive());
});
Can anyone help me, please? I have no more ideas for solving my problem :/
You can't use XMLHttpRequest inside of a service worker. Instead, you need to use the Fetch API.
Based on your code, it's the Firebase client library that's using XMLHttpRequest under the hood. I don't think that you have any control over that (at least not based on what I see in the current JavaScript documentation for Firebase).
Instead of using the Firebase client library in your service worker, you could try using the REST API directly, using fetch() to send your HTTP requests. You'll be responsible for things like authentication and setting whatever user ids, etc. that the client library would otherwise handle for you, but I think that's your best bet inside of a service worker.
Since version 9 the Firebase Web SDK uses fetch instead of XMLHttpRequest. So it works inside a service worker.

Fetch cached data Vue CLI Vuex PWA

How do I get my cached data from service worker in to the vuex store in offline mode?
The app works in offline mode in the browser, but when I add the site to home screen with the manifest.json file included, it won't show the cached data and only the general js, css and html.
I'm having a hard time figuring out, how I get my cached data from my PWA. I already have the data cached. The problem is retrieving it back to the vuex store state called "games", to display when the app is offline.
The vue.config.js code for caching the api call for the service worker.
module.exports = {
pwa: {
workboxPluginMode: "GenerateSW",
workboxOptions: {
navigateFallback: "/index.html",
runtimeCaching: [{
urlPattern: new RegExp('API_URL'),
handler: 'networkFirst',
options: {
networkTimeoutSeconds: 20,
cacheName: 'api-cache',
cacheableResponse: {
statuses: [0, 200],
},
},
}]
}
}
};
As you can see in the image above the code, it has stored the cache "api-cache" with the objects from the API.
Now I want to use this data in the cache from api-cache on my site, when the site is offline.
So my question is:
How do I get my cached data from service worker in to the vuex store in offline mode, when a user has added the app to their home screen?
You're thinking about this in the wrong way. You don't need the service worker to do anything for you. It's already doing it by providing you with a cache implementation. Instead, you need to use the navigator.onLine hook to determine if they have internet access. If not, then hydrate your store from the cache and make sure to subscribe to any mutations and push the state back into the cache, like this:
if (!navigator.onLine) {
const state = hydrateFromCache()
store.subscribe((mutation, state) => cache.setItems(state)
}
Where the hydrateFromCache method simply pulls the store in from the cache and hydrates the state of all vuex modules.

Categories