FCM with NextJs - firebase-cloud-messaging

I am trying to integrate FCM with next.js ..but its showing the following error. Can anyone please help me with the next.config.js file?
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 WindowController.eval (webpack-internal:///./node_modules/#firebase/messaging/dist/index.esm.js:1053:45)
at step (webpack-internal:///./node_modules/tslib/tslib.es6.js:124:23)
at Object.eval [as throw] (webpack-internal:///./node_modules/tslib/tslib.es6.js:105:53)
at rejected (webpack-internal:///./node_modules/tslib/tslib.es6.js:96:65)

you don't need to configure the next.config.js, you just have to add the serviceWorker in the Public folder with the name of firebase-messaging-sw.js
They mention the following in the documentation:
The messaging service requires a firebase-messaging-sw.js file. Unless you already have a firebase-messaging-sw.js file, create an empty file with that name and place it in the root of your domain before retrieving a token. You can add meaningful content to the file later in the client configuration process.
Visit: Access the registration token
your serviceWorker should look like this:
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.1/firebase-messaging.js');
firebase.initializeApp({
apiKey: 'api-key',
authDomain: 'project-id.firebaseapp.com',
databaseURL: 'https://project-id.firebaseio.com',
projectId: 'project-id',
storageBucket: 'project-id.appspot.com',
messagingSenderId: 'sender-id',
appId: 'app-id',
measurementId: 'G-measurement-id',
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
self.registration.showNotification(notificationTitle,
notificationOptions);
});
Remember use ENV on your initializeApp

Example with nextjs, Firebase V9 cloud messaging
Generate VapidKey
add config variables of your project
After, you execute de npm run dev. It will appear the token in the console, you can use that token to send a test message. and it will send the foreground and background notification.

Related

react native supabase facebook login redirect callback site url

I am trying to login with facebook using Supabase on ios emulator. After logging in with Facebook, it redirects me back to localhost. I don't know exactly what to do on this side. Can you help me? I'm still very new.
const onHandleLogin = async () => {
const {data, error} = await supabase.auth.signInWithOAuth({
provider: 'facebook',
});
if (error) {
return;
}
if (data.url) {
const supported = await Linking.canOpenURL(data.url);
if (supported) {
await Linking.openURL(data.url);
}
}
};
After the login process, it still stays on the localhost address on the browser. My purpose is to send it to the application and get token information via the url, but I have no idea how.
I think I need to make changes here but I don't know what to write in the site url because it is a mobile application.
Thanks for your support and replies.
I tried to login with facebook using supabase, but after logging in, it keeps me in safari and gives token information on localhost. I want to direct the application after the login process and get the token information.
You will need to create a deep link for your React Native app: https://reactnative.dev/docs/linking and then set this as your redirect URL. Here a similar example with Flutter: https://supabase.com/docs/guides/getting-started/tutorials/with-flutter#setup-deep-links

Unable to receive push notification send via Firebase console in iOS using React-Native-Firebase

I have tried to follow this guide https://rnfirebase.io/messaging/usage/ios-setup to set up push notifications for my React-Native application. In particular, I have done the following:
Adding Push Notification & Background Mode capabilities(with Remote fetch and background activities)
Register a key(with APNs enabled) in Apple developer account and upload it to firebase console settings with the correct KeyID(obtained when registering the key) and TeamID(obtained from developer's membership detail)
Register the App Identifier(with APNs capability). Since there are two bundle Identifiers for my project - org.reactjs.native.example.AppName and org.test.AppName, I have tried both but none works.
Register a Provisioning profile. I believe this wil automatically sync with my Xcode.
I note that I can further configure the APNs capability after registering the App Identifier, but this is not mentioned in the guide and I didn't do that:
To configure push notifications for this App ID, a Client SSL Certificate that allows your notification server to connect to the Apple Push Notification Service is required. Each App ID requires its own Client SSL Certificate. Manage and generate your certificates below.
In my React-Native application, I have the following code:
const App => {
useEffect(() => {
async function requestUserPermission() {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
console.log('Authorization status:', authStatus);
}
}
requestPermission();
});
useEffect(() => {
async function getToken() {
await messaging().registerDeviceForRemoteMessages();
const token = await messaging().getToken();
console.log(token);
}
getToken();
});
...
}
After accepting the notification permission request when the app launch. This will output the FCMs token, which I use to send a test message in the Firebase console.
Did I miss any steps? Is it possible to send push notifications in React-Native debug built running under metro in the first place? Thank you in advance.
I figured out the problem. It is because I used a different bundle ID when building the product in XCode and when registering the identifier in Apple Developer Account. The steps by steps does work as of writing.

React Native with axios - Network error calling localhost with self signed https endpoint

I created service in Visual Studio with Conveyor extension to make it accessible in local network. I installed certificate on my Android device so there is green padlock when calling it in browser and service works fine.
However when calling it from React Native app with axios then i get Network error.
That's my code:
const fetchData = async () => {
console.log('url', `${Settings.API_URL}/location/GetDataByMyIp`);
try {
const result = await axios(
`${Settings.API_URL}/location/GetDataByMyIp`,
);
console.log('result', result);
ipData = {
city: result.data.city,
longitude: result.data.longitude,
latitude: result.data.latitude,
};
} catch (e) {
console.log('error', e);
}
};
await fetchData();
In console i see:
url https://192.168.1.14:45455/api/location/GetDataByMyIp
error Error: Network Error
at createError (path_to_app\node_modules\axios\lib\core\createError.js:16)
at EventTarget.handleError (path_to_app\node_modules\axios\lib\adapters\xhr.js:83)
at EventTarget.dispatchEvent (path_to_app\node_modules\event-target-shim\dist\event-target-shim.js:818)
at EventTarget.setReadyState (path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:575)
at EventTarget.__didCompleteResponse (path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:389)
at path_to_app\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:502
at RCTDeviceEventEmitter.emit (path_to_app\node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:189)
at MessageQueue.__callFunction (path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:425)
at path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:112
at MessageQueue.__guard (path_to_app\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:373)
I tried to add this line to AndroidManifest.xml application tag but still have the error
android:usesCleartextTraffic="true"
Some solutions say about adding as 2nd parameter to axios, but it doesn't work with React Native.
new https.Agent({
rejectUnauthorized: false,
});
I tried to call some other service from the internet and then error was gone.
Is there some solution to this? I haven't found anything more. My last idea is to host service on Azure so I'll have properly signed SSL, but i guess it has to be a way to run it locally.
Edit: It works through http

How do you communicate between firebase service worker and Vue/Vuex web app

We are running a Vue application that has a firebase service worker running "next" to it.
The service worker has been initiated as such:
// main.js
import firebase from 'firebase/app'
import 'firebase/messaging'
...
const firebase_config = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_PROJECT_ID.firebaseapp.com',
databaseURL: 'https://YOUR_PROJECT_ID.firebaseio.com',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_PROJECT_ID.appspot.com',
messagingSenderId: 'YOUR_MESSAGING_SEND_ID'
}
console.log('firebase', firebase)
new Vue({
...
In the firebase-messaging-sw.js file (in the public directory) we handle the data message as such:
// firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.6.2/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/7.6.2/firebase-messaging.js')
// for some reason it requires this again
const firebase_config = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_PROJECT_ID.firebaseapp.com',
databaseURL: 'https://YOUR_PROJECT_ID.firebaseio.com',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_PROJECT_ID.appspot.com',
messagingSenderId: 'YOUR_MESSAGING_SEND_ID'
appId: 'YOUR_APPID'
}
firebase.initializeApp(firebase_config)
const messaging = firebase.messaging()
messaging.setBackgroundMessageHandler(function(payload) {
//////////////////////////////////////////////////////
// I want to access the vue or vuex component here
//////////////////////////////////////////////////////
return true
}
How do you make a call back to the vue/vuex store, or access one of the DOM elements, if it is there?
EDIT
Here is some more detail:
It seems that the way you communicate from the service worker to the main app it with the postMessage() function.
The postMessange() function needs a client object that can be found by the fetch event and a fetch event is triggered when you access a url.
Unfortunately vue does not seem to fetch url's as it is a singe page app therefore you cant get a client therefore you can't use it to run a postMessage() (unless I got that wrong, all help is appreciated)
Here is the code I got for posting a message on fetch event:
addEventListener('fetch', event => {
event.waitUntil(
(async function() {
// Exit early if we don't have access to the client.
// Eg, if it's cross-origin.
if (!event.clientId) return
// Get the client.
const client = await clients.get(event.clientId)
// Exit early if we don't get the client.
// Eg, if it closed.
if (!client) return
// Send a message to the client.
client.postMessage({
msg: 'Hey I just got a fetch from you!',
url: event.request.url
})
})()
)
})
In React (yes I know this is Vue, hold your horses) handling asynchronous events is usually done using a middleware. Redux-saga is one of these middlewares and it supports Event channels which give you a way to tie your external event logic (e.g. your firebase event) to your internal store using puts or calls to your vuex actions.
Redux-saga is not tied to redux (as it seems) and there are several adapters that support this (vuex-redux-saga, vuex-nia or vuex-coolstory). There are some more listed here: https://yarnpkg.com/?q=vuex%20saga&p=1
Please be wary that I personally did not use any of these libraries, though I have come to love the Saga middleware approach.

problem accessing elements using id/name for login form in cypress

I am trying to login to a form written in angular js but cypress throws the following exception:
Uncaught TypeError: $(...).materialScrollTop is not a function
This error originated from your application code, not from Cypress.
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.
https://on.cypress.io/uncaught-exception-from-application
This is the cypress login code:
context('TestLogin', () => {
it('Test Login', () => {
cy.visit('url');
cy.get('input[id=Email]').type('email', {force: true});
cy.get('input[id=Password]').type('passcode', { force: true });
cy.get('button[type=submit]').click();
})
})
Since the login has a csrf token, I have used cy.request() as follows and I do get a response with status code 200 but when re-loading the site it goes back to login page.
describe("Tests for AntiForgeryToken", function () {
// variable from config, that contain Identity Server URL
const identityUrl = Cypress.config("identityServerUrl")
// command declaration that we are going to use in tests
// allows us to create request to server
Cypress.Commands.add("loginByToken", function (token, login, password) {
cy.request({
method: "POST",
failOnStatusCode: false,
url: `${identityUrl}/Account/Login`,
form: true,
body: {
email: login,
password: password,
__RequestVerificationToken: token,
RememberLogin: false
}
})
})
it("Should parse token from response body and return 200", function () {
cy.request(`${identityUrl}/Account/Login`)
.its("body")
.then((body) => {
const $html = Cypress.$(body)
// when the page is rendered
// we are trying to find the Request Token in the body of page
const token = $html.find("input[name=__RequestVerificationToken]").val()
// POST request with token and login data
// then we simply verify whether Indentity Server authorized us
cy.loginByToken(token, "test#test.com", "Test_1234")
.then((resp) => {
expect(resp.status).to.eq(200)
})
})
cy.visit(`${identityUrl}/Account/`);
})
Cypress documentation didn't provide much info about the exception.
Any insights from cypress experts are helpful.
As evident from the error, Cypress is failing the test as it found an exception in your application,this is not a cypress level exception but an uncaught exception in your app which is causing cypress to fail the test, this is pretty useful as you can check if its an actual error in your app and log it for the dev team to fix, check if you are able to reproduce this manually, either way i think the application code should be fixed to either fix the bug or catch the exception and return a valuable error message. If you want to disable this feature you can turn off all uncaught exception handling, so in your index.js or whatever file is the entry point add the following:
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
// you can also add a Debugger here to analyze the error
debugger;
return false;
});
not sure if turning this off will help as looks like there is something in your application which could be an issue, but this is just for informational purposes that you can turn this feature off if you needed to.
Here is the documentation for further reading : Cypress Events documentation
hope this helps