Skip to content

Commit

Permalink
fix: add push notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
Nekitech committed May 4, 2024
1 parent 7e32519 commit 2396ac0
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 53 deletions.
53 changes: 39 additions & 14 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,28 @@ import * as http from "node:http";
import {NotificationsService} from "./app/services/Notifications/NotificationsService";
import {postgresBookingRepository} from "./infrastructure/db/repository/PostgresQL/BookingRepoImplement";
import {postgresUserRepository} from "./infrastructure/db/repository/PostgresQL/UserRepoImplement";
import {Expo} from "expo-server-sdk";
import {CronJob} from "cron";
import {FirebaseService} from "./app/services/Firebase/FirebaseService";


dotenv.config();
const app = express();
const router = express.Router();
const server = http.createServer(app)
const expo = new Expo()

app.use(express.json())
app.use(cookieParser())
app.use(multer().any());
app.use(
bodyParser.urlencoded({
extended: false,
})
bodyParser.urlencoded({
extended: false,
})
);
app.use(cors({
credentials: true,
origin: process.env.CLIENT_URL,
credentials: true,
origin: process.env.CLIENT_URL,
}))


Expand All @@ -44,30 +48,51 @@ userRoutes.initRoutes(router)
bookingRoutes.initRoutes(router)
uploadRoutes.initRoutes(router)

router.post("/saveTokenApp", async (req, res) => {
const {token, userId} = req.body;
await firebase.saveToken(token, userId);
res.status(200).send("Token saved")
})

app.use("/api", router)

app.use(ErrorMiddleware)

// Firebase
const firebase = new NotificationsService(postgresBookingRepository, postgresUserRepository)
const firebase = new FirebaseService(postgresBookingRepository, postgresUserRepository)
const notificationExpo = new NotificationsService(postgresBookingRepository,
postgresUserRepository,
firebase,
expo)

router.post("/saveTokenApp", async (req, res) => {
const {token, userId} = req.body;
await firebase.saveToken(token, userId);
res.status(200).send("Token saved")
})

router.post("/sendNotification", async (req, res) => {
const {userId} = req.body;
const {token} = await firebase.getToken(userId);
console.log(userId, token)
expo.sendPushNotificationsAsync([{
to: token,
sound: 'default',
title: 'Backend hello',
body: 'asdasdasdasdasd!',
data: {someData: 'kek'},
}])
res.status(200).send("Notification send")
})

// new CronJob('*/20 * * * * *', async () => {
// notificationExpo.sendAlertReservationNotification()
// }).start()

const port = process.env.PORT;

app.get('/api', (req, res) => {
res.send('Express + TypeScript Server');
res.send('Express + TypeScript Server');
});



server.listen(port, () => {
console.log(`⚡️[server]: Server is running at http://localhost:${port}/api`);
console.log(`⚡️[server]: Server is running at http://localhost:${port}/api`);
});


Expand Down
44 changes: 44 additions & 0 deletions src/app/services/Firebase/FirebaseService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {child, get, getDatabase, ref, set} from "firebase/database";
import process from "node:process";
import {initializeApp} from "firebase/app";
import {BookingRepo} from "../../repositories/BookingRepo";
import {UserRepo} from "../../repositories/UserRepo";

export class FirebaseService {

private readonly db: any
private dbRef: any
constructor(
private BookingRepo: BookingRepo,
private UserRepo: UserRepo,
) {

const firebaseConfig = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
databaseURL: process.env.FIREBASE_DATABASE_URL
};

initializeApp(firebaseConfig);
// const analytics = getAnalytics(app);

this.db = getDatabase()
this.dbRef = ref(this.db)
}

async saveToken(token: string, userId: string) {

const values = (await get(child(this.dbRef, `userTokens/${userId}`))).val() ?? {};
const payload = {...values, token};
set(ref(this.db, `userTokens/${userId}`), payload);
}

async getToken(userId: string){
return (await get(child(this.dbRef, `userTokens/${userId}`))).val() ?? {};
}
}
67 changes: 31 additions & 36 deletions src/app/services/Notifications/NotificationsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,17 @@ import {BookingStatus} from "../../../infrastructure/shared/types/Booking";
import {equalDateTimeBookingExpired} from "../../../infrastructure/helpers/Date";
import {BookingRepo} from "../../repositories/BookingRepo";
import {UserRepo} from "../../repositories/UserRepo";
import {child, get, getDatabase, ref, set} from "firebase/database"
import {initializeApp} from "firebase/app";
import * as process from "node:process";

import {FirebaseService} from "../Firebase/FirebaseService";
import {Expo} from "expo-server-sdk";


export class NotificationsService {
private db: any
private dbRef: any
constructor(
private BookingRepo: BookingRepo,
private UserRepo: UserRepo,
private firebase: FirebaseService,
private expo: Expo
) {

const firebaseConfig = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
measurementId: process.env.FIREBASE_MEASUREMENT_ID,
databaseURL: process.env.FIREBASE_DATABASE_URL
};

const app = initializeApp(firebaseConfig);
// const analytics = getAnalytics(app);

this.db = getDatabase()
this.dbRef = ref(this.db)
}


Expand All @@ -40,36 +21,50 @@ export class NotificationsService {
id: true
})
listUsers.forEach(async ({id: user_id}: { id: number }) => {

const listBookings = await this.BookingRepo.getBySelect({
status: BookingStatus.CREATED,
user_id
}, {
time_from: true,
time_to: true,
date: true
date: true,
equipment_id: true
})

listBookings?.forEach((booking: any) => {
const {date, time_to} = booking
const {date, time_to} = booking;
if (equalDateTimeBookingExpired(date, time_to)) {
console.log("check")
this.firebase.getToken(String(user_id)).then((data: any) => {
const {token} = data;
if(token) {
this.sendExpoNotification(token, {
date,
time_to
})
} else {
console.log("Token not found!")
}

})
}
})

})
}

async saveToken(token: string, userId: string) {

const values = (await get(child(this.dbRef, `userTokens/${userId}`))).val() ?? {};
const payload = {...values, token};
set(ref(this.db, `userTokens/${userId}`), payload);
private async sendExpoNotification(token: string, data: any) {
this.expo.sendPushNotificationsAsync([
{
to: token,
sound: 'default',
title: 'Внимание!',
body: 'Ваша бронь просрочена!',
data,
}
])
console.log("send notification!")
}

async getTokens() {
const values = (await get(child(this.dbRef, `userTokens`))).val() ?? {};
return values;
}

}

4 changes: 1 addition & 3 deletions src/infrastructure/helpers/Date.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import moment from "moment";
import moment from "moment-timezone"


export const equalDateTimeBookingExpired = (date: Date, time_to: string) => {
//@ts-ignore
const currDate = moment().tz("Europe/Moscow").format("YYYY-MM-DD")
const comparisonDate = moment(date).format("YYYY-MM-DD")
if(currDate > comparisonDate) {
return true
} else if(currDate == comparisonDate) {
//@ts-ignore
const currTime = moment().tz("Europe/Moscow").format("HH:mm")
return currTime > time_to
}
Expand Down

0 comments on commit 2396ac0

Please sign in to comment.