diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 415a835b4..60553299c 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -6,6 +6,10 @@
bootstrap="tests/bootstrap.php"
colors="true"
>
+
+
+
+
tests/Unit
diff --git a/src/Firebase/Auth.php b/src/Firebase/Auth.php
index 65a1e68b5..d079c22f3 100644
--- a/src/Firebase/Auth.php
+++ b/src/Firebase/Auth.php
@@ -59,7 +59,7 @@
/**
* @internal
*/
-final class Auth implements Contract\Auth
+final class Auth implements Contract\Auth, Contract\Transitional\FederatedUserFetcher
{
private readonly Parser $jwtParser;
@@ -210,6 +210,22 @@ public function getUserByPhoneNumber(Stringable|string $phoneNumber): UserRecord
return UserRecord::fromResponseData($data['users'][0]);
}
+ public function getUserByProviderUid(Stringable|string $providerId, Stringable|string $providerUid): UserRecord
+ {
+ $providerId = (string) $providerId;
+ $providerUid = (string) $providerUid;
+
+ $response = $this->client->getUserByProviderUid($providerId, $providerUid);
+
+ $data = Json::decode((string) $response->getBody(), true);
+
+ if (empty($data['users'][0])) {
+ throw new UserNotFound("No user with federated account ID '{$providerId}:{$providerUid}' found.");
+ }
+
+ return UserRecord::fromResponseData($data['users'][0]);
+ }
+
public function createAnonymousUser(): UserRecord
{
return $this->createUser(CreateUser::new());
diff --git a/src/Firebase/Auth/ApiClient.php b/src/Firebase/Auth/ApiClient.php
index 7775c6153..749a53bd9 100644
--- a/src/Firebase/Auth/ApiClient.php
+++ b/src/Firebase/Auth/ApiClient.php
@@ -118,6 +118,16 @@ public function getUserByPhoneNumber(string $phoneNumber): ResponseInterface
return $this->requestApi($url, ['phoneNumber' => [$phoneNumber]]);
}
+ /**
+ * @throws AuthException
+ */
+ public function getUserByProviderUid(string $providerId, string $uid): ResponseInterface
+ {
+ $url = $this->awareAuthResourceUrlBuilder->getUrl('/accounts:lookup');
+
+ return $this->requestApi($url, ['federatedUserId' => [['providerId' => $providerId, 'rawId' => $uid]]]);
+ }
+
/**
* @throws AuthException
*/
diff --git a/src/Firebase/Contract/Transitional/FederatedUserFetcher.php b/src/Firebase/Contract/Transitional/FederatedUserFetcher.php
new file mode 100644
index 000000000..c894ddb01
--- /dev/null
+++ b/src/Firebase/Contract/Transitional/FederatedUserFetcher.php
@@ -0,0 +1,24 @@
+auth->getUserByPhoneNumber($phoneNumber);
}
+ #[Test]
+ public function getUserByNonExistingProviderUid(): void
+ {
+ if ($this->auth instanceof FederatedUserFetcher) {
+ $provider = 'test.com';
+ $uid = 'u' . random_int(1000000, 9999999);
+
+ $this->expectException(UserNotFound::class);
+ /** @phpstan-ignore method.notFound */
+ $this->auth->getUserByProviderUid($provider, $uid);
+ } else {
+ $this->fail("{\$this->auth} does not implement FederatedUserFetcher as expected - cannot test");
+ }
+ }
+
#[Test]
public function createUser(): void
{