Skip to content

Commit 6579e7e

Browse files
committed
Added GetUser method to FirebaseAuth that can be used to retrieve a UserRecord object for the specified user ID.
1 parent 31e55ef commit 6579e7e

File tree

7 files changed

+397
-8
lines changed

7 files changed

+397
-8
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public class FirebaseUserManagerTest
3232
[Fact]
3333
public void InvalidUidForUserRecord()
3434
{
35-
Assert.Throws<ArgumentException>(() => new UserRecord(null));
35+
Assert.Throws<ArgumentException>(() => new UserRecord((string)null));
36+
Assert.Throws<ArgumentException>(() => new UserRecord((Internal.GetAccountInfoResponse.User)null));
3637
Assert.Throws<ArgumentException>(() => new UserRecord(string.Empty));
3738
Assert.Throws<ArgumentException>(() => new UserRecord(new string('a', 129)));
3839
}
@@ -76,8 +77,16 @@ public async Task GetUserById()
7677
{
7778
var handler = new MockMessageHandler()
7879
{
79-
Response = new UserRecord("user1"),
80+
Response = new Internal.GetAccountInfoResponse()
81+
{
82+
Kind = "identitytoolkit#GetAccountInfoResponse",
83+
Users = new List<Internal.GetAccountInfoResponse.User>()
84+
{
85+
new Internal.GetAccountInfoResponse.User() { UserID = "user1" },
86+
},
87+
},
8088
};
89+
8190
var factory = new MockHttpClientFactory(handler);
8291
var userManager = new FirebaseUserManager(
8392
new FirebaseUserManagerArgs

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseAuth.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ public async Task<FirebaseToken> VerifyIdTokenAsync(
263263
.ConfigureAwait(false);
264264
}
265265

266+
/// <summary>
267+
/// Gets a <see cref="UserRecord"/> object containig information about the user who's
268+
/// user ID was specified in <paramref name="uid"/>.
269+
/// </summary>
270+
/// <param name="uid">The user ID for the user who's data is to be retrieved..</param>
271+
/// <returns>A task that completes with a <see cref="UserRecord"/> representing
272+
/// a user with the specified user ID.</returns>
273+
/// <exception cref="ArgumentException">If user ID argument is null or empty.</exception>
274+
/// <exception cref="FirebaseException">If a user cannot be found with the specified user ID.</exception>
275+
public async Task<UserRecord> GetUser(string uid)
276+
{
277+
return await this.userManager.Value.GetUserById(uid);
278+
}
279+
266280
/// <summary>
267281
/// Sets the specified custom claims on an existing user account. A null claims value
268282
/// removes any claims currently set on the user account. The claims must serialize into

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ public async Task<UserRecord> GetUserById(
8181
{
8282
{ "localId", uid },
8383
};
84-
var response = await this.PostAndDeserializeAsync<JObject>(
84+
85+
var response = await this.PostAndDeserializeAsync<Internal.GetAccountInfoResponse>(
8586
getUserPath, payload, cancellationToken).ConfigureAwait(false);
86-
if (response == null || uid != (string)response["localId"])
87+
if (response == null || response.Users == null || response.Users.Count == 0)
8788
{
8889
throw new FirebaseException($"Failed to get user: {uid}");
8990
}
9091

91-
return new UserRecord((string)response["localId"]);
92+
return new UserRecord(response.Users[0]);
9293
}
9394

9495
/// <summary>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Newtonsoft.Json;
5+
6+
namespace FirebaseAdmin.Auth.Internal
7+
{
8+
/// <summary>
9+
/// JSON data binding for GetAccountInfoResponse messages sent by Google identity toolkit service.
10+
/// </summary>
11+
public sealed class GetAccountInfoResponse
12+
{
13+
/// <summary>
14+
/// Gets or sets a string representing what kind of account is represented by this object.
15+
/// </summary>
16+
[JsonProperty(PropertyName = "kind")]
17+
public string Kind { get; set; }
18+
19+
/// <summary>
20+
/// Gets or sets a list of provider users linked to this account.
21+
/// </summary>
22+
[JsonProperty(PropertyName = "users")]
23+
public List<User> Users { get; set; }
24+
25+
/// <summary>
26+
/// JSON data binding for user records.
27+
/// </summary>
28+
public sealed class User
29+
{
30+
/// <summary>
31+
/// Gets or sets the user's ID.
32+
/// </summary>
33+
[JsonProperty(PropertyName = "localId")]
34+
public string UserID { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets the user's email address.
38+
/// </summary>
39+
[JsonProperty(PropertyName = "email")]
40+
public string Email { get; set; }
41+
42+
/// <summary>
43+
/// Gets or sets the user's phone number.
44+
/// </summary>
45+
[JsonProperty(PropertyName = "phoneNumber")]
46+
public string PhoneNumber { get; set; }
47+
48+
/// <summary>
49+
/// Gets or sets a value indicating whether the user's email address is verified or not.
50+
/// </summary>
51+
[JsonProperty(PropertyName = "emailVerified")]
52+
public bool EmailVerified { get; set; }
53+
54+
/// <summary>
55+
/// Gets or sets the user's display name.
56+
/// </summary>
57+
[JsonProperty(PropertyName = "displayName")]
58+
public string DisplayName { get; set; }
59+
60+
/// <summary>
61+
/// Gets or sets the URL for the user's photo.
62+
/// </summary>
63+
[JsonProperty(PropertyName = "photoUrl")]
64+
public string PhotoUrl { get; set; }
65+
66+
/// <summary>
67+
/// Gets or sets a value indicating whether the user is disabled or not.
68+
/// </summary>
69+
[JsonProperty(PropertyName = "disabled")]
70+
public bool Disabled { get; set; }
71+
72+
/// <summary>
73+
/// Gets or sets a list of provider-specified data for this user.
74+
/// </summary>
75+
[JsonProperty(PropertyName = "providerUserInfo")]
76+
public List<Provider> Providers { get; set; }
77+
78+
/// <summary>
79+
/// Gets or sets the timestamp representing the time that the user account was created.
80+
/// </summary>
81+
[JsonProperty(PropertyName = "createdAt")]
82+
public long CreatedAt { get; set; }
83+
84+
/// <summary>
85+
/// Gets or sets the timestamp representing the last time that the user has logged in.
86+
/// </summary>
87+
[JsonProperty(PropertyName = "lastLoginAt")]
88+
public long LastLoginAt { get; set; }
89+
90+
/// <summary>
91+
/// Gets or sets the timestamp representing the time that the user account was first valid.
92+
/// </summary>
93+
[JsonProperty(PropertyName = "validSince")]
94+
public long ValidSince { get; set; }
95+
96+
/// <summary>
97+
/// Gets or sets the user's custom claims.
98+
/// </summary>
99+
[JsonProperty(PropertyName = "customAttributes")]
100+
public string CustomClaims { get; set; }
101+
}
102+
103+
/// <summary>
104+
/// JSON data binding for provider data.
105+
/// </summary>
106+
public sealed class Provider
107+
{
108+
/// <summary>
109+
/// Gets or sets the user's ID.
110+
/// </summary>
111+
[JsonProperty(PropertyName = "uid")]
112+
public string UserID { get; set; }
113+
114+
/// <summary>
115+
/// Gets or sets the user's display name.
116+
/// </summary>
117+
[JsonProperty(PropertyName = "displayName")]
118+
public string DisplayName { get; set; }
119+
120+
/// <summary>
121+
/// Gets or sets the user's email address.
122+
/// </summary>
123+
[JsonProperty(PropertyName = "email")]
124+
public string Email { get; set; }
125+
126+
/// <summary>
127+
/// Gets or sets the user's phone number.
128+
/// </summary>
129+
[JsonProperty(PropertyName = "phoneNumber")]
130+
public string PhoneNumber { get; set; }
131+
132+
/// <summary>
133+
/// Gets or sets the URL for the user's photo.
134+
/// </summary>
135+
[JsonProperty(PropertyName = "photoUrl")]
136+
public string PhotoUrl { get; set; }
137+
138+
/// <summary>
139+
/// Gets or sets the provider's ID.
140+
/// </summary>
141+
[JsonProperty(PropertyName = "providerId")]
142+
public string ProviderID { get; set; }
143+
}
144+
}
145+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace FirebaseAdmin.Auth
6+
{
7+
/// <summary>
8+
/// Contains metadata regarding how a user is known by a particular identity provider (IdP).
9+
/// Instances of this class are immutable and thread safe.
10+
/// </summary>
11+
public sealed class ProviderUserInfo
12+
{
13+
private string uid;
14+
private string displayName;
15+
private string email;
16+
private string phoneNumber;
17+
private string photoUrl;
18+
private string providerId;
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="ProviderUserInfo"/> class with data provided by an authentication provider.
22+
/// </summary>
23+
/// <param name="provider">The deserialized JSON user data from the provider.</param>
24+
public ProviderUserInfo(Internal.GetAccountInfoResponse.Provider provider)
25+
{
26+
this.uid = provider.UserID;
27+
this.displayName = provider.DisplayName;
28+
this.email = provider.Email;
29+
this.phoneNumber = provider.PhoneNumber;
30+
this.photoUrl = provider.PhotoUrl;
31+
this.providerId = provider.ProviderID;
32+
}
33+
34+
/// <summary>
35+
/// Gets the user's ID.
36+
/// </summary>
37+
public string UserID { get => this.uid; }
38+
39+
/// <summary>
40+
/// Gets the user's display name.
41+
/// </summary>
42+
public string DisplayName { get => this.displayName; }
43+
44+
/// <summary>
45+
/// Gets the user's email address.
46+
/// </summary>
47+
public string Email { get => this.email; }
48+
49+
/// <summary>
50+
/// Gets the user's phone number.
51+
/// </summary>
52+
public string PhoneNumber { get => this.phoneNumber; }
53+
54+
/// <summary>
55+
/// Gets the URL for the user's photo/avatar.
56+
/// </summary>
57+
public string PhotoUrl { get => this.photoUrl; }
58+
59+
/// <summary>
60+
/// Gets the user's ID specified by the provider.
61+
/// </summary>
62+
public string ProviderId { get => this.providerId; }
63+
}
64+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Newtonsoft.Json;
5+
6+
namespace FirebaseAdmin.Auth
7+
{
8+
/// <summary>
9+
/// Contains additional metadata associated with a user account.
10+
/// </summary>
11+
public sealed class UserMetadata
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="UserMetadata"/> class with the specified creation and last sign-in timestamps.
15+
/// </summary>
16+
/// <param name="creationTimestamp">A timestamp representing the date and time that the user account was created.</param>
17+
/// <param name="lastSignInTimestamp">A timestamp representing the date and time that the user account was last signed-on to.</param>
18+
public UserMetadata(long creationTimestamp, long lastSignInTimestamp)
19+
{
20+
this.CreationTimestamp = creationTimestamp;
21+
this.LastSignInTimestamp = lastSignInTimestamp;
22+
}
23+
24+
/// <summary>
25+
/// Gets or sets a timestamp representing the date and time that the account was created.
26+
/// </summary>
27+
[JsonProperty("creationTimestamp")]
28+
public long CreationTimestamp { get; set; }
29+
30+
/// <summary>
31+
/// Gets or sets a timestamp representing the last time that the user has logged in.
32+
/// </summary>
33+
[JsonProperty("lastSignInTimestamp")]
34+
public long LastSignInTimestamp { get; set; }
35+
}
36+
}

0 commit comments

Comments
 (0)