Getting error "FirebaseError: Messaging: We are unable to register the default service worker." setting up messaging with Sveltekit - firebase-cloud-messaging

Full error message
FirebaseError: Messaging: We are unable to register the default service worker. Failed
to register a ServiceWorker for scope ('http://localhost:3000/firebase-cloud-messaging-
push-scope') with script ('http://localhost:3000/firebase-messaging-sw.js'): A bad HTTP
response code (404) was received when fetching the script. (messaging/failed-service-
worker-registration).
at it.<anonymous> (window-controller.ts:166:27)
at tslib.es6.js:100:23
at Object.throw (tslib.es6.js:81:53)
at i (tslib.es6.js:72:64)
Contents of src/service-worker.js
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-app.js")
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-messaging.js")
firebase.initializeApp({
apiKey: '...',
authDomain: '...',
projectId: '...',
storageBucket: '...',
messagingSenderId: '...',
appId: '...',
})
const messaging = firebase.messaging()
Contents of src/firebase-messaging-sw
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-app.js")
importScripts("https://www.gstatic.com/firebasejs/8.2.7/firebase-messaging.js")
firebase.initializeApp({
'messagingSenderId': "..."
})
const messaging = firebase.messaging()
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('../firebase-messaging-sw.js')
.then(function (registration) {
console.log('Registration successful, scope is:', registration.scope);
}).catch(function (err) {
console.log('Service worker registration failed, error:', err);
});
}
contents of src/jsconfig.json
"include": [
"src/**/*.d.ts",
"src/**/*.js",
"src/**/*.svelte",
"src/firebase-messaging-sw.js"
]
method that's calling firebase-messaging
messaging
.requestPermission() //It takes permission from user whether website can send notifications.
.then(res => {
console.log('Notification permission granted.', res)
if (messaging.getToken()) {
// THIS PROMISE SHOWS "pending" WITH STATE "rejected".
console.log('Token will come.', messaging.getToken())
}
return messaging.getToken()
})
.then(token => {
console.log(`token`, token)
})
.catch(error => {
// ERROR COMES FROM HERE
console.log('error under got token.', error)
})
.catch(function (err) {
errorElement.innerHTML = ErrElem.innerHTML + '; ' + err
console.log('Unable to get permission to notify.', err)
})
As a "throwing it against the wall to see what sticks", firebase-messaging-sw.js was added to jsconfig.json.
Chrome network tab shows firebase-messaging-sw as "pending", size "0 bytes".
Basically, it looks like this file is being missed. The serviceworker does it's job, and then when firebase comes back looking for this script in the root of the project, it either can't or won't find it.
How do I setup so that firebase can find this script?

You need to add empty firebase-messaging-sw.js file to your [YOUR_PROJECT]/public folder.
The goal is to have firebase-messaging-sw.js file straight in [YOUR_PROJECT]/dist folder for firebase to be able to fetch it from server.
Svelte is automatically copying files from public to dist while building the app.

I placed both scripts at the static folder and it worked in localhost at least

Related

how to access exceptions thrown by Nestjs from frontend?

I am building backend API with Nestjs and I want to access exeptions from frontend
this is a simple example from login endpoint when user enters non-existent email :
const user = await this.userModel.findOne({ email });
if (!user) {
throw new NotFoundException('email does not exist .');
}
now when I send request from my Nextjs application like this :
await axios
.post(`http://127.0.0.1:5000/user/login`, {
email: values.email,
password: values.password,
})
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log("Login catched an error : ", error);
});
I get the NotFoundException as error:
now I want to get the status of this error (404 in this case),is it possible ?
It's an AxiosError, so you should be able to access error.response.status as shown in Axios's documentation

FCM not working in Firebase Cloud Function because admin sdk authentication-error

I am currently trying to send FCM using Firebase Cloud Function in the Flutter WEB environment. But it doesn't work very well
My Problem
My index.js Code
/* eslint-disable max-len */
const admin = require("firebase-admin");
const {applicationDefault} = require("firebase-admin/app");
const functions = require("firebase-functions");
const cors = require("cors")({origin: true});
admin.initializeApp({credential: applicationDefault(), databaseURL: "https://<PROJECT-ID>.firebaseio.com"});
const messaging = admin.messaging();
exports.sendNoti = functions.runWith({
allowInvalidAppCheckToken: true}).https.onRequest(async (req, res) => {
cors(req, res, async () =>{
if (res.app == undefined) {
console.log("App Check failed-precondition / The function must be called from an App Check verified app.");
}
console.log(res.app);
try {
await messaging.sendToDevice(req.body.data.targetDevices, {
notification: {
title: req.body.data.messageTitle,
body: req.body.data.messageBody,
},
});
res.set("Access-Control-Allow-Origin", "*");
res.status(200).send({"status": "success", "data": "GOOD"});
return true;
} catch (ex) {
console.log(ex);
res.set("Access-Control-Allow-Origin", "*");
res.status(200).send({"status": "fail", "data": ex});
return ex;
}
});
});
Error Message
{errorInfo: {code: messaging/authentication-error, message: An error occurred when trying to authenticate to the FCM servers. Make sure the credential used to authenticate this SDK has the proper permissions. See https://firebase.google.com/docs/admin/setup for setup instructions. Raw server response: "HTML CODE
". Status code: 401.}, codePrefix: messaging}
My Try
credential: admin.credential.applicationDefault(),
credential: admin.credential.cert("service.json"),
Use OnCall function
Use AppCheck

Office web add-in in JS and login with SSAL : interaction_in_progress after login

I'm trying to get an access token from Microsoft to connect to Graph API, by using a client that is a web add-in in Word 365 desktop (pure JS, not made with Angular or Node).
To authenticate, this is the code I'm using:
window.Office.onReady(() => {
initMsalInstance();
});
function initMsalInstance() {
myMSALObj = new msal.PublicClientApplication({
auth: {
clientId: "...",
authority: "...",
redirectUri: "",
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: true
}
});
myMSALObj.handleRedirectPromise()
.then((response) => {
if (response) {
console.log(response);
} else {
console.log('noresp');
}
})
.catch((error) => {
console.log(error)
});
}
function signIn() {
myMSALObj.loginRedirect({
scopes: ['user.read', 'files.read.all']
});
}
I just have a button that calls the "signIn()" method, then it opens Chrome, I'm loggin in, and I'm redirected to the page I selected.
Unfortunately, in the add-in, nothing happens, my handleRedirectPromise() doesn't seem to get called, so I don't have the response and the token.
If I'm trying to click on "sign in" again, then this is the error I get:
interaction_in_progress: Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API. For more visit: aka.ms/msaljs/browser-errors.
What can I do to complete the process and get my token into my Office 365 Word Web add-in?
You are getting this error because of this piece of code:
msalInstance.loginRedirect(loginRequest);
This code looks into the session storage for the key MSAL.[clientId].interaction.status and other temp values required for redirection process.
If such value exist and it's value equals the 'interaction_in_progress' then error will be thrown.
This is the known issue in MSAL.
Follow these steps to resolve this issue.
Account selection logic is app dependent and adjust as needed for different use cases. Set active account on page load.
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
msalInstance.setActiveAccount(accounts[0]);
}
msalInstance.addEventCallback((event) => {
if (event.eventType === EventType.LOGIN_SUCCESS && event.payload.account) {
const account = event.payload.account;
msalInstance.setActiveAccount(account);
}
}, error=>{
console.log('error', error);
});
console.log('get active account', msalInstance.getActiveAccount());
// handle auth redirect/do all initial setup for MSAL
msalInstance.handleRedirectPromise().then(authResult=>{
// Check if user signed in
const account = msalInstance.getActiveAccount();
if(!account){
// redirect anonymous user to login page
msalInstance.loginRedirect();
}
}).catch(err=>{
// TODO: Handle errors
console.log(err);
});

GraphQL / Apollo - Can't get NetworkError

I'm unable to get any network error with my Apollo Client, only GraphQL errors.
I have the client set up like so:
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const client = new ApolloClient({
link: ApolloLink.from([
errorLink,
new HttpLink({
uri: 'http://localhost:4000/graphql'
}),
]),
});
On the server i'm making a request which i parse like this:
.then(res => {
if (res.ok) {
return { blah: res.json(), count };
}
throw new Error();
})
.catch(error => {
throw new AuthenticationError('Must Authenticate');
});
The AuthenicationError just bubbles up to the Client as a GraphQL Error ([GraphQL error]: Message: Must Authenticate,, i basically just want to be able to get the HTTP Status Code from the server request, on the client.
Thanks
Your client side implementation looks correct.
I guess you are using express with some graphl middleware to handle the requests. The main thing is that you would need to handle the authentication process before the graphql middleware comes in to play.
So the authentication is a graphql mutation which you handle directly. In my case it looked kind of like this:
...
const app = express();
app.use(
"/graphql",
bodyParser.json(),
(request, response, next) => authenticationMiddleware(request) // authentication is handled before graphql
.then(() => next())
.catch(error => next(error)),
graphqlExpress(request => {
return {
schema: executable.schema,
context: {
viewer: request.headers.viewer
},
};
}),
);
...
app.listen(...)
Another possibility would be to add the status code to the error response in the graphql errors.
But that depends on the npm package you are using.
e.g. formatError in apollo-server-graphql
https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#constructor-options-lt-ApolloServer-gt

404 error on post request in ec2 server

I deployed my mean stack project to amazon ec2 instance and i tried to login and it returns me 404 error (Cannot POST /api/user/login). Both the client side and server side code is inside the same project. When i run the project from localhost it works fine. What could be the issue ? Thanks.
Edit : Code snipped added
From controller
var credentials = {
email : $scope.user.email,
password : $scope.user.password
};
User.login(credentials)
.then(function (response) {
// Administrator. Redirect to /admin.html page
if($cookies.get('userType') == 0) {
$location.path('/admin');
}
console.log("From controller "+ response);
})
.catch(function(error) {
console.log(error);
})
From service
$http({
method : 'POST',
url : '/api/user/login',
data : data
})
.success(function (data, status, headers, config) {
object = JSON.parse(Util.toObject(data));console.log(object._id);
$cookies.put('userType', object['status']); // 0 for admin
$cookies.put('email', object.email); // store the email for session.
console.log(object['status'] + ' ' + object.email);
$('#loginModal').hide();
deffered.resolve(Util.toObject(data));
})
.error(function (data, status, headers, config) {
console.log("Error in Login "+ status);
deffered.reject(data);
})
BE route
app.use('/api/admin', require('./admin'));
Inside admin folder, index.js file
router.post('/login', controller.login);
controller.login file
exports.login = function(req, res) {
console.log(req.body);
User.find(req.body, function(err, data) {
if (err) {
console.log(' Error in finding the data .. ');
}
else {
console.log(' Data found in login ' + JSON.stringify(data));
res.status(200).json(data);
}
});
};
Found the issue in the end. I added '/' at the end of each API endpoint and it worked.