Skip to content

Commit 48d3762

Browse files
committed
Initial commit
0 parents  commit 48d3762

17 files changed

+2928
-0
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/config/firebase-messaging-sw.js

.eslintrc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.gitignore

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
.pnpm-debug.log*
27+
28+
# local env files
29+
.env
30+
.env*.local
31+
32+
# vercel
33+
.vercel
34+
35+
# typescript
36+
*.tsbuildinfo
37+
38+
.idea
39+
40+
public/firebase-messaging-sw.js
41+
public/firebase-messaging-sw.map

README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# nextjs-firebase-messaging
2+
3+
Example Next.js application integrated with firebase messaging.
4+
5+
## Getting Started
6+
7+
First create an `.env` file in the root directory. It should include following variables.
8+
9+
```bash
10+
11+
12+
```
13+
14+
First, run the development server:
15+
16+
```bash
17+
npm run dev
18+
# or
19+
yarn dev
20+
```
21+
22+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
23+
24+
##

next-env.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
4+
// NOTE: This file should not be edited
5+
// see https://nextjs.org/docs/basic-features/typescript for more information.

next.config.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/** @type {import('next').NextConfig} */
2+
const { withServiceWorker } = require('next-sw');
3+
4+
const nextConfig = withServiceWorker({
5+
reactStrictMode: true,
6+
serviceWorker: {
7+
name: 'firebase-messaging-sw.js',
8+
entry: 'src/config/firebase-messaging-sw.js',
9+
livereload: true
10+
}
11+
})
12+
13+
module.exports = nextConfig

package.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "nextjs-firebase-messaging",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "next dev",
7+
"build": "next build",
8+
"start": "next start",
9+
"lint": "next lint"
10+
},
11+
"dependencies": {
12+
"firebase": "^9.6.11",
13+
"next": "12.1.5",
14+
"react": "18.0.0",
15+
"react-dom": "18.0.0"
16+
},
17+
"devDependencies": {
18+
"@types/node": "17.0.25",
19+
"@types/react": "18.0.6",
20+
"@types/react-dom": "18.0.2",
21+
"eslint": "8.13.0",
22+
"eslint-config-next": "12.1.5",
23+
"next-sw": "^1.2.0",
24+
"typescript": "4.6.3"
25+
}
26+
}

public/favicon.ico

25.3 KB
Binary file not shown.

public/vercel.svg

+4
Loading

src/config/firebase-messaging-sw.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js');
2+
importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js');
3+
4+
firebase.initializeApp({
5+
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
6+
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
7+
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_ID,
8+
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
9+
})
10+
11+
const messaging = firebase.messaging()
12+
13+
messaging.onBackgroundMessage(function (payload) {
14+
if (Notification.permission === 'granted') {
15+
if (navigator.serviceWorker)
16+
navigator.serviceWorker.getRegistration().then(async function (reg) {
17+
if (reg)
18+
await reg.showNotification(payload.notification.title, {
19+
body: payload.notification.body,
20+
});
21+
});
22+
}
23+
})

src/config/firebase.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Import the functions you need from the SDKs you need
2+
import * as firebase from "firebase/app";
3+
import {getMessaging, getToken, onMessage} from 'firebase/messaging';
4+
// TODO: Add SDKs for Firebase products that you want to use
5+
// https://firebase.google.com/docs/web/setup#available-libraries
6+
7+
const firebaseCloudMessaging = {
8+
//checking whether token is available in indexed DB
9+
tokenInlocalforage: async () => {
10+
return localStorage.getItem('fcm_token')
11+
},
12+
//initializing firebase app
13+
init: async function () {
14+
if (!firebase.getApps().length) {
15+
firebase.initializeApp({
16+
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
17+
authDomain: process.env.NEXT_PUBLIC_FIREBAE_AUTH_DOMAIN,
18+
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
19+
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
20+
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_ID,
21+
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
22+
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
23+
})
24+
25+
try {
26+
const messaging = getMessaging()
27+
const tokenInLocalForage = await this.tokenInlocalforage()
28+
//if FCM token is already there just return the token
29+
if (tokenInLocalForage !== null) {
30+
return tokenInLocalForage
31+
}
32+
//requesting notification permission from browser
33+
const status = await Notification.requestPermission()
34+
if (status && status === 'granted') {
35+
//getting token from FCM
36+
const fcm_token = await getToken(messaging,{
37+
vapidKey: 'BC-1yQLXhWuv5Dfs90bL3iHxFLzzsTwFFqXO4vErr4a0s-fxgPJ56EqvjVyNEyIJnFCIrVXyeOgVDHl2qATMDhc'
38+
})
39+
if (fcm_token) {
40+
//setting FCM token in indexed db using localforage
41+
localStorage.setItem('fcm_token', fcm_token)
42+
console.log('fcm token', fcm_token)
43+
//return the FCM token after saving it
44+
return fcm_token
45+
}
46+
}
47+
} catch (error) {
48+
console.error(error)
49+
return null
50+
}
51+
}
52+
},
53+
getMessage: async function() {
54+
if(firebase.getApps().length > 0) {
55+
try {
56+
const messaging = getMessaging();
57+
onMessage(messaging, (payload) => {
58+
console.log("Message Received", payload)
59+
} )
60+
61+
}catch (error) {
62+
63+
}
64+
}
65+
}
66+
}
67+
export { firebaseCloudMessaging }

src/pages/_app.tsx

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import '../../styles/globals.css'
2+
import type { AppProps } from 'next/app'
3+
import {useEffect} from "react";
4+
import {firebaseCloudMessaging} from "../config/firebase";
5+
6+
function MyApp({ Component, pageProps }: AppProps) {
7+
8+
9+
10+
useEffect(() => {
11+
setToken()
12+
// this is working
13+
if ('serviceWorker' in navigator) {
14+
navigator.serviceWorker.addEventListener('message', (event) => console.log('event for the service worker', event))
15+
}
16+
async function setToken() {
17+
try {
18+
const token = await firebaseCloudMessaging.init()
19+
if (token) {
20+
console.log('token', token)
21+
// not working
22+
await firebaseCloudMessaging.getMessage()
23+
}
24+
} catch (error) {
25+
console.log(error)
26+
}
27+
}
28+
}, [])
29+
30+
31+
return <Component {...pageProps} />
32+
}
33+
34+
export default MyApp

src/pages/index.tsx

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import type { NextPage } from 'next'
2+
import Head from 'next/head'
3+
import Image from 'next/image'
4+
import styles from '../../styles/Home.module.css'
5+
6+
const Home: NextPage = () => {
7+
return (
8+
<div className={styles.container}>
9+
<Head>
10+
<title>Create Next App</title>
11+
<meta name="description" content="Generated by create next app" />
12+
<link rel="icon" href="/favicon.ico" />
13+
</Head>
14+
15+
<main className={styles.main}>
16+
<h1 className={styles.title}>
17+
Welcome to <a href="https://nextjs.org">Next.js!</a>
18+
</h1>
19+
20+
<p className={styles.description}>
21+
Get started by editing{' '}
22+
<code className={styles.code}>pages/index.tsx</code>
23+
</p>
24+
25+
<div className={styles.grid}>
26+
<a href="https://nextjs.org/docs" className={styles.card}>
27+
<h2>Documentation &rarr;</h2>
28+
<p>Find in-depth information about Next.js features and API.</p>
29+
</a>
30+
31+
<a href="https://nextjs.org/learn" className={styles.card}>
32+
<h2>Learn &rarr;</h2>
33+
<p>Learn about Next.js in an interactive course with quizzes!</p>
34+
</a>
35+
36+
<a
37+
href="https://github.com/vercel/next.js/tree/canary/examples"
38+
className={styles.card}
39+
>
40+
<h2>Examples &rarr;</h2>
41+
<p>Discover and deploy boilerplate example Next.js projects.</p>
42+
</a>
43+
44+
<a
45+
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
46+
className={styles.card}
47+
>
48+
<h2>Deploy &rarr;</h2>
49+
<p>
50+
Instantly deploy your Next.js site to a public URL with Vercel.
51+
</p>
52+
</a>
53+
</div>
54+
</main>
55+
56+
<footer className={styles.footer}>
57+
<a
58+
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
59+
target="_blank"
60+
rel="noopener noreferrer"
61+
>
62+
Powered by{' '}
63+
<span className={styles.logo}>
64+
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
65+
</span>
66+
</a>
67+
</footer>
68+
</div>
69+
)
70+
}
71+
72+
export default Home

0 commit comments

Comments
 (0)