Răsfoiți Sursa

fix double fcm token

Alexander Musikhin 1 lună în urmă
părinte
comite
f110b0a631

+ 16 - 5
app/Http/Controllers/Auth/LoginController.php

@@ -20,7 +20,9 @@ class LoginController extends Controller
     |
     */
 
-    use AuthenticatesUsers;
+    use AuthenticatesUsers {
+        logout as traitLogout;
+    }
 
     /**
      * Where to redirect users after login.
@@ -58,10 +60,11 @@ class LoginController extends Controller
             if ($request->hasSession()) {
                 $request->session()->put('auth.password_confirmed_at', time());
             }
-            if($request->session()->has('token_fcm')) {
-                User::query()
-                    ->where('email', $request->email)
-                    ->update(['token_fcm' => $request->session()->get('token_fcm')]);
+            if ($request->session()->has('token_fcm') && auth()->id()) {
+                $token = trim((string)$request->session()->get('token_fcm'));
+                if ($token !== '') {
+                    User::assignUniqueFcmToken((int)auth()->id(), $token);
+                }
             }
             return $this->sendLoginResponse($request);
         }
@@ -74,5 +77,13 @@ class LoginController extends Controller
         return $this->sendFailedLoginResponse($request);
     }
 
+    public function logout(Request $request)
+    {
+        if ($request->user()) {
+            User::clearFcmToken((int)$request->user()->id);
+        }
+
+        return $this->traitLogout($request);
+    }
 
 }

+ 4 - 0
app/Http/Controllers/UserController.php

@@ -163,6 +163,7 @@ class UserController extends Controller
     public function deleteProfile(Request $request)
     {
         User::query()->where('id', '=', $request->user()->id)->delete();
+        User::clearFcmToken((int)$request->user()->id);
         Auth::logout();
         return redirect()->route('login')->with(['success' => 'Профиль удалён!']);
     }
@@ -209,6 +210,9 @@ class UserController extends Controller
         $impersonator = User::query()->find($impersonatorId);
 
         if (!$impersonator) {
+            if ($request->user()) {
+                User::clearFcmToken((int)$request->user()->id);
+            }
             Auth::logout();
             $request->session()->invalidate();
             $request->session()->regenerateToken();

+ 7 - 6
app/Http/Middleware/CatchTokenFcmMiddleware.php

@@ -16,13 +16,14 @@ class CatchTokenFcmMiddleware
      */
     public function handle(Request $request, Closure $next): Response
     {
-        if(isset($request->app) && isset($request->token_fcm)) {
-            if(auth()->check()) {
-                User::query()
-                    ->where('id', auth()->user()->id)
-                    ->update(['token_fcm' => $request->token_fcm]);
+        if (isset($request->app) && isset($request->token_fcm)) {
+            $token = trim((string)$request->token_fcm);
+
+            if ($token !== '' && auth()->check()) {
+                User::assignUniqueFcmToken((int)auth()->id(), $token);
             }
-            session(['token_fcm' => $request->token_fcm]);
+
+            session(['token_fcm' => $token]);
         }
         return $next($request);
     }

+ 22 - 0
app/Models/User.php

@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
 use Illuminate\Database\Eloquent\SoftDeletes;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
+use Illuminate\Support\Facades\DB;
 
 class User extends Authenticatable implements MustVerifyEmail
 {
@@ -78,4 +79,25 @@ class User extends Authenticatable implements MustVerifyEmail
     {
         return $this->userNotifications()->whereNull('read_at');
     }
+
+    public static function assignUniqueFcmToken(int $userId, string $token): void
+    {
+        DB::transaction(function () use ($userId, $token) {
+            self::query()
+                ->where('id', '!=', $userId)
+                ->where('token_fcm', $token)
+                ->update(['token_fcm' => null]);
+
+            self::query()
+                ->where('id', $userId)
+                ->update(['token_fcm' => $token]);
+        });
+    }
+
+    public static function clearFcmToken(int $userId): void
+    {
+        self::query()
+            ->where('id', $userId)
+            ->update(['token_fcm' => null]);
+    }
 }