diff --git a/app/realtime.php b/app/realtime.php index b4bcd37034..17edb7bbbc 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -1527,7 +1527,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re $database, $presenceDocument, $presenceId, - $userId, + (string) $user->getSequence(), function () use ($project): void { if ($project !== null && !$project->isEmpty()) { triggerPresenceUsage(1, $project->getId()); diff --git a/src/Appwrite/Databases/PresenceState.php b/src/Appwrite/Databases/PresenceState.php index 32a11ce7be..8ba5b23eab 100644 --- a/src/Appwrite/Databases/PresenceState.php +++ b/src/Appwrite/Databases/PresenceState.php @@ -58,7 +58,7 @@ class PresenceState Database $dbForProject, Document $presenceDocument, string $presenceId, - string $userId, + mixed $userInternalId, ?callable $onPresenceCreated = null ): Document { if ($presenceId !== 'unique()') { @@ -69,14 +69,14 @@ class PresenceState try { if ($dbForProject->getAdapter()->getSupportForUpsertOnUniqueIndex()) { - $presenceCreated = $dbForProject->findOne(self::COLLECTION_ID, [Query::equal('userId', [$userId])])->isEmpty(); + $presenceCreated = $dbForProject->findOne(self::COLLECTION_ID, [Query::equal('userInternalId', [$userInternalId])])->isEmpty(); $presence = $dbForProject->upsertDocument(self::COLLECTION_ID, $presenceDocument); } else { $presence = $this->transactionalUpsertForUser( $dbForProject, $presenceDocument, $presenceId, - $userId, + $userInternalId, $presenceCreated ); } @@ -101,18 +101,18 @@ class PresenceState Database $dbForProject, Document $presenceDocument, string $presenceId, - string $userId, + mixed $userInternalId, ?bool &$presenceCreated = null ): Document { - return $dbForProject->withTransaction(function () use ($dbForProject, $presenceDocument, $presenceId, $userId, &$presenceCreated) { - $existingPresence = $dbForProject->findOne(self::COLLECTION_ID, [Query::equal('userId', [$userId])]); + return $dbForProject->withTransaction(function () use ($dbForProject, $presenceDocument, $presenceId, $userInternalId, &$presenceCreated) { + $existingPresence = $dbForProject->findOne(self::COLLECTION_ID, [Query::equal('userInternalId', [$userInternalId])]); if ($existingPresence->isEmpty()) { $presenceCreated = true; return $dbForProject->createDocument(self::COLLECTION_ID, $presenceDocument); } - // Lock current state to avoid races while resolving upsert by userId. + // Lock current state to avoid races while resolving upsert by userInternalId. $currentPresence = $dbForProject->getDocument(self::COLLECTION_ID, $existingPresence->getId(), forUpdate: true); if ($currentPresence->isEmpty()) { diff --git a/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php b/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php index 8297639045..0be1c58402 100644 --- a/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php +++ b/src/Appwrite/Platform/Modules/Presences/HTTP/Upsert.php @@ -147,9 +147,13 @@ class Upsert extends PlatformAction throw new Exception(Exception::USER_NOT_FOUND, params: [$userId]); } - $userInternalId = $fetchedUser->getSequence(); + $userInternalId = (string) $fetchedUser->getSequence(); $resolvedUserId = $fetchedUser->getId(); } + + if (empty($userInternalId)) { + throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to resolve valid user internal ID.'); + } $isGraphQL = $request->getHeader('x-appwrite-source') === 'graphql'; $presenceData = [ @@ -170,7 +174,7 @@ class Upsert extends PlatformAction $dbForProject, $presenceDocument, $presenceId, - $resolvedUserId, + $userInternalId, fn () => $usage->addMetric(METRIC_USERS_PRESENCE, 1) ); $queueForEvents->setParam('presenceId', $presence->getId());