Возможный фикс невозможности отправить уведомление.

Добавлена возможность отправки сообщений вручную.
This commit is contained in:
2024-11-01 02:00:33 +04:00
parent 979877532c
commit fe88c685e0
4 changed files with 54 additions and 20 deletions

View File

@@ -7,7 +7,7 @@
"license": "UNLICENSED", "license": "UNLICENSED",
"scripts": { "scripts": {
"build": "nest build", "build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\"",
"start": "nest start", "start": "nest start",
"start:dev": "nest start --watch", "start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch", "start:debug": "nest start --debug --watch",
@@ -17,7 +17,8 @@
"test:watch": "jest --watch", "test:watch": "jest --watch",
"test:cov": "jest --coverage", "test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json" "test:e2e": "jest --config ./test/jest-e2e.json",
"precommit": "npm run format && npm run lint"
}, },
"dependencies": { "dependencies": {
"@nestjs/cache-manager": "^2.2.2", "@nestjs/cache-manager": "^2.2.2",

View File

@@ -23,6 +23,12 @@ import {
ApiResponse, ApiResponse,
ApiTags, ApiTags,
} from "@nestjs/swagger"; } from "@nestjs/swagger";
import { AuthRoles } from "../auth/auth-role.decorator";
import { UserRole } from "../users/user-role.enum";
import {
TokenMessage,
TopicMessage,
} from "firebase-admin/lib/messaging/messaging-api";
@ApiTags("v1/fcm") @ApiTags("v1/fcm")
@ApiBearerAuth() @ApiBearerAuth()
@@ -33,6 +39,16 @@ export class FirebaseAdminController {
constructor(private readonly firebaseAdminService: FirebaseAdminService) {} constructor(private readonly firebaseAdminService: FirebaseAdminService) {}
@ApiOperation({ summary: "Отправка уведомления" })
@ApiResponse({ status: HttpStatus.OK })
@Post("post")
@HttpCode(HttpStatus.OK)
@ResultDto(null)
@AuthRoles([UserRole.ADMIN])
async post(@Body() message: TopicMessage | TokenMessage) {
await this.firebaseAdminService.send(message);
}
@ApiOperation({ summary: "Установка FCM токена пользователем" }) @ApiOperation({ summary: "Установка FCM токена пользователем" })
@ApiResponse({ @ApiResponse({
status: HttpStatus.OK, status: HttpStatus.OK,

View File

@@ -13,6 +13,9 @@ import { firebaseConstants } from "../contants";
import { UsersService } from "../users/users.service"; import { UsersService } from "../users/users.service";
import { User } from "../users/entity/user.entity"; import { User } from "../users/entity/user.entity";
import { TokenMessage } from "firebase-admin/lib/messaging/messaging-api";
import { FcmUser } from "../users/entity/fcm-user.entity";
import { plainToInstance } from "class-transformer";
@Injectable() @Injectable()
export class FirebaseAdminService implements OnModuleInit { export class FirebaseAdminService implements OnModuleInit {
@@ -37,7 +40,22 @@ export class FirebaseAdminService implements OnModuleInit {
const topicMessage = message as TopicMessage; const topicMessage = message as TopicMessage;
topicMessage.topic = topic; topicMessage.topic = topic;
await this.messaging.send(topicMessage); await this.send(topicMessage);
}
async send(message: TopicMessage | TokenMessage): Promise<void> {
await this.messaging.send(message);
}
private getFcmOrDefault(user: User, token: string): FcmUser {
if (!user.fcm) {
return plainToInstance(FcmUser, {
token: token,
topics: [],
} as FcmUser);
}
return user.fcm;
} }
async updateToken( async updateToken(
@@ -45,8 +63,8 @@ export class FirebaseAdminService implements OnModuleInit {
token: string, token: string,
): Promise<{ userDto: User; isNew: boolean }> { ): Promise<{ userDto: User; isNew: boolean }> {
const isNew = user.fcm === null; const isNew = user.fcm === null;
const fcm = this.getFcmOrDefault(user, token);
const fcm = !isNew ? user.fcm : { token: token, topics: [] };
if (!isNew) { if (!isNew) {
if (fcm.token === token) return { userDto: user, isNew: false }; if (fcm.token === token) return { userDto: user, isNew: false };
@@ -65,18 +83,20 @@ export class FirebaseAdminService implements OnModuleInit {
} }
async unsubscribe(user: User, topics: Set<string>): Promise<User> { async unsubscribe(user: User, topics: Set<string>): Promise<User> {
if (!user.fcm) throw new Error("User does not have fcm data!");
const fcm = user.fcm; const fcm = user.fcm;
const currentTopics = new Set(fcm.topics); const newTopics = new Set<string>();
for (const topic of topics) { for (const topic of topics) {
if (!fcm.topics.includes(topic)) continue; if (!fcm.topics.includes(topic)) continue;
await this.messaging.unsubscribeFromTopic(fcm.token, topic); await this.messaging.unsubscribeFromTopic(fcm.token, topic);
currentTopics.delete(topic); newTopics.add(topic);
} }
if (currentTopics.size === fcm.topics.length) return user; if (newTopics.size === fcm.topics.length) return user;
fcm.topics = Array.from(currentTopics); fcm.topics = Array.from(newTopics);
return await this.usersService.update({ return await this.usersService.update({
where: { id: user.id }, where: { id: user.id },
@@ -89,20 +109,22 @@ export class FirebaseAdminService implements OnModuleInit {
topics: Set<string>, topics: Set<string>,
force: boolean = false, force: boolean = false,
): Promise<User> { ): Promise<User> {
const newTopics = new Set([...this.defaultTopics, ...topics]); const additionalTopics = new Set([...this.defaultTopics, ...topics]);
const fcm = user.fcm; const fcm = user.fcm;
const currentTopics = new Set(fcm.topics); const newTopics = new Set(fcm.topics);
for (const topic of newTopics) { for (const topic of additionalTopics) {
if (fcm.topics.includes(topic) && !force) continue; if (force)
await this.messaging.unsubscribeFromTopic(fcm.token, topic);
else if (fcm.topics.includes(topic)) continue;
else newTopics.add(topic);
await this.messaging.subscribeToTopic(fcm.token, topic); await this.messaging.subscribeToTopic(fcm.token, topic);
currentTopics.add(topic);
} }
if (currentTopics.size === fcm.topics.length) return user; if (newTopics.size === fcm.topics.length) return user;
fcm.topics = Array.from(currentTopics); fcm.topics = Array.from(newTopics);
return await this.usersService.update({ return await this.usersService.update({
where: { id: user.id }, where: { id: user.id },

View File

@@ -514,11 +514,6 @@ export class V2ScheduleParser {
): Array<V2LessonDto> { ): Array<V2LessonDto> {
const row = time.xlsxRange.s.r; const row = time.xlsxRange.s.r;
if (typeof column !== "number") {
console.log(typeof column);
console.log(column);
}
// name // name
const rawName = trimAll( const rawName = trimAll(
V2ScheduleParser.getCellData(workSheet, row, column)?.replaceAll( V2ScheduleParser.getCellData(workSheet, row, column)?.replaceAll(