guoziyun há 9 meses atrás
pai
commit
1a436aed15

+ 43 - 12
oms/dist/src/controllers/userController.js

@@ -34,6 +34,14 @@ const USER_MODEL_KEYS = [
     "firstLoginAt",
     "lastActiveAt",
 ];
+/**
+ * 检查错误是否为 FCM 令牌失效错误。
+ * @param error 错误对象
+ * @returns 如果是令牌失效错误则返回 true
+ */
+function isTokenInvalidationError(error) {
+    return error && (error.code === "messaging/registration-token-not-registered" || error.code === "messaging/invalid-registration-token");
+}
 class UserController {
     /**
      * 处理创建新用户的请求。
@@ -259,18 +267,30 @@ class UserController {
                 extend: extend || "",
             });
             // 5. 调用 FCMService 发送消息
-            const result = await fcmService.sendMessage(user.fmToken, messageData);
+            let fcmResult;
+            try {
+                fcmResult = await fcmService.sendMessage(user.fmToken, messageData);
+            }
+            catch (fcmError) {
+                fcmResult = fcmError;
+            }
             let messageStatus = 1;
             let errorMessage = null;
             let fcmReceipt = null;
-            if (result instanceof Error) {
+            if (fcmResult instanceof Error) {
                 messageStatus = -1;
-                errorMessage = result.message;
-                console.warn(`send message to ${uid} failed: ${result.message}`);
+                errorMessage = fcmResult.message;
+                console.warn(`[FCM] 发送消息至 UID ${uid} 失败: ${fcmResult.message}`);
+                // --- IMPORTANT: 如果错误是令牌失效,则清空该用户的 fmToken ---
+                if (isTokenInvalidationError(fcmResult)) {
+                    console.warn(`[FCM] 检测到无效令牌,自动清除 UID ${uid} 的 fmToken。`);
+                    await userService_1.default.updateUser(uid, { fmToken: null });
+                    errorMessage += " (Token cleared)";
+                }
             }
             else {
-                fcmReceipt = result;
-                console.log(`send message to ${uid} success!`);
+                fcmReceipt = fcmResult;
+                console.log(`[FCM] 发送消息至 UID ${uid} 成功!`);
             }
             // 6. 更新 MessageRecord 记录
             await messageRecordModel_1.MessageRecord.findByIdAndUpdate(messageRecord._id, {
@@ -288,7 +308,7 @@ class UserController {
         }
         catch (error) {
             // 7. 捕获并处理所有其他异常
-            console.error(`Error sending message to UID ${uid}:`, error);
+            console.error(`[API] 发送消息至 UID ${uid} 时发生意外错误:`, error);
             res.status(500).json({ message: "An unexpected error occurred while sending the message.", error: error.message });
         }
     }
@@ -353,16 +373,27 @@ class UserController {
                     extend: extend || "",
                 });
                 // Send message.
-                const result = await fcmService.sendMessage(user.fmToken, messageData);
+                let fcmResult;
+                try {
+                    fcmResult = await fcmService.sendMessage(user.fmToken, messageData);
+                }
+                catch (fcmError) {
+                    fcmResult = fcmError;
+                }
                 let messageStatus = 1;
                 let errorMessage = null;
                 let fcmReceipt = null;
-                if (result instanceof Error) {
+                if (fcmResult instanceof Error) {
                     messageStatus = -1;
-                    errorMessage = result.message;
+                    errorMessage = fcmResult.message;
+                    // --- IMPORTANT: 如果错误是令牌失效,则清空该用户的 fmToken ---
+                    if (isTokenInvalidationError(fcmResult)) {
+                        await userService_1.default.updateUser(uid, { fmToken: null });
+                        errorMessage += " (Token cleared)";
+                    }
                 }
                 else {
-                    fcmReceipt = result;
+                    fcmReceipt = fcmResult;
                 }
                 // Update the MessageRecord with the send result.
                 await messageRecordModel_1.MessageRecord.findByIdAndUpdate(messageRecord._id, {
@@ -379,7 +410,7 @@ class UserController {
                 }
             }
             catch (error) {
-                console.error(`Error processing bulk message for UID ${uid}:`, error);
+                console.error(`[API] Error processing bulk message for UID ${uid}:`, error);
                 results.push({ uid, status: "failed", error: error.message });
             }
         });

+ 44 - 12
oms/src/controllers/userController.ts

@@ -47,6 +47,15 @@ interface IBulkMessageResult {
   error?: string | null;
 }
 
+/**
+ * 检查错误是否为 FCM 令牌失效错误。
+ * @param error 错误对象
+ * @returns 如果是令牌失效错误则返回 true
+ */
+function isTokenInvalidationError(error: any): boolean {
+  return error && (error.code === "messaging/registration-token-not-registered" || error.code === "messaging/invalid-registration-token");
+}
+
 class UserController {
   /**
    * 处理创建新用户的请求。
@@ -284,19 +293,31 @@ class UserController {
       });
 
       // 5. 调用 FCMService 发送消息
-      const result = await fcmService.sendMessage(user.fmToken, messageData);
+      let fcmResult: any;
+      try {
+        fcmResult = await fcmService.sendMessage(user.fmToken, messageData);
+      } catch (fcmError: any) {
+        fcmResult = fcmError;
+      }
 
       let messageStatus = 1;
       let errorMessage = null;
       let fcmReceipt = null;
 
-      if (result instanceof Error) {
+      if (fcmResult instanceof Error) {
         messageStatus = -1;
-        errorMessage = result.message;
-        console.warn(`send message to ${uid} failed: ${result.message}`);
+        errorMessage = fcmResult.message;
+        console.warn(`[FCM] 发送消息至 UID ${uid} 失败: ${fcmResult.message}`);
+
+        // --- IMPORTANT: 如果错误是令牌失效,则清空该用户的 fmToken ---
+        if (isTokenInvalidationError(fcmResult)) {
+          console.warn(`[FCM] 检测到无效令牌,自动清除 UID ${uid} 的 fmToken。`);
+          await userService.updateUser(uid, { fmToken: null });
+          errorMessage += " (Token cleared)";
+        }
       } else {
-        fcmReceipt = result;
-        console.log(`send message to ${uid} success!`);
+        fcmReceipt = fcmResult;
+        console.log(`[FCM] 发送消息至 UID ${uid} 成功!`);
       }
 
       // 6. 更新 MessageRecord 记录
@@ -314,7 +335,7 @@ class UserController {
       }
     } catch (error: any) {
       // 7. 捕获并处理所有其他异常
-      console.error(`Error sending message to UID ${uid}:`, error);
+      console.error(`[API] 发送消息至 UID ${uid} 时发生意外错误:`, error);
       res.status(500).json({ message: "An unexpected error occurred while sending the message.", error: error.message });
     }
   }
@@ -386,17 +407,28 @@ class UserController {
         });
 
         // Send message.
-        const result = await fcmService.sendMessage(user.fmToken, messageData);
+        let fcmResult: any;
+        try {
+          fcmResult = await fcmService.sendMessage(user.fmToken, messageData);
+        } catch (fcmError: any) {
+          fcmResult = fcmError;
+        }
 
         let messageStatus = 1;
         let errorMessage = null;
         let fcmReceipt = null;
 
-        if (result instanceof Error) {
+        if (fcmResult instanceof Error) {
           messageStatus = -1;
-          errorMessage = result.message;
+          errorMessage = fcmResult.message;
+
+          // --- IMPORTANT: 如果错误是令牌失效,则清空该用户的 fmToken ---
+          if (isTokenInvalidationError(fcmResult)) {
+            await userService.updateUser(uid, { fmToken: null });
+            errorMessage += " (Token cleared)";
+          }
         } else {
-          fcmReceipt = result;
+          fcmReceipt = fcmResult;
         }
 
         // Update the MessageRecord with the send result.
@@ -413,7 +445,7 @@ class UserController {
           results.push({ uid, status: "failed", error: errorMessage, recordId: messageRecord._id });
         }
       } catch (error: any) {
-        console.error(`Error processing bulk message for UID ${uid}:`, error);
+        console.error(`[API] Error processing bulk message for UID ${uid}:`, error);
         results.push({ uid, status: "failed", error: error.message });
       }
     });

+ 1 - 1
oms/src/models/userModel.ts

@@ -22,7 +22,7 @@ export interface IUser extends Document {
   apiLevel?: number; // api版本号
   versionName?: string; // 软件版本
   versionCode?: number; // 软件编号
-  fmToken?: string; // firebase message token
+  fmToken?: string | null; // <--- 关键修改:明确允许 null 类型,以兼容数据库清除操作
   tags?: string[]; // 用户画像(基础维度、内容偏好维度、社区属性维度等),现在是字符串数组
   firstLoginAt?: Date; // 首次登录时间
   lastActiveAt?: Date; // 上次活跃时间