Skip to content

Commit 24991d3

Browse files
Merge remote-tracking branch 'upstream/master' into list-users
2 parents c16710d + a7ee4bb commit 24991d3

File tree

20 files changed

+2275
-411
lines changed

20 files changed

+2275
-411
lines changed

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
# Unreleased
22

3-
- [added] Implemented the `GetUserById()` API in the `FirebaseUserManager` class.
3+
- [added] Implemented the `UpdateUserAsync()` API.
4+
- [added] Implemented the `CreateUserAsync()` and `UserRecordArgs` APIs.
45

5-
-
6+
# v1.6.0
7+
8+
- [added] `WebpushFcmOptions` added to the `WebpushConfig` class.
9+
- [added] Implemented the `GetUserByEmailAsync()` and `GetUserByPhoneNumberAsync()`
10+
APIs in the `FirebaseAuth` class.
11+
12+
# v1.5.0
13+
14+
- [added] Implemented the `GetUserAsync()` API in the `FirebaseAuth` class.
15+
- [added] Implemented the `DeleteUserAsync()` API in the `FirebaseAuth` class.
616

717
# v1.4.0
818

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAuthTest.cs

Lines changed: 192 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,169 @@ public async Task SetCustomUserClaimsWithWrongUid()
119119
var customClaims = new Dictionary<string, object>();
120120

121121
await Assert.ThrowsAsync<FirebaseException>(
122-
async () => await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync("mock-uid", customClaims));
122+
async () => await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync("non.existing", customClaims));
123+
}
124+
125+
[Fact]
126+
public async Task CreateUserWithParams()
127+
{
128+
var randomUser = RandomUser.Create();
129+
var args = new UserRecordArgs()
130+
{
131+
Uid = randomUser.Uid,
132+
Email = randomUser.Email,
133+
PhoneNumber = randomUser.PhoneNumber,
134+
DisplayName = "Random User",
135+
PhotoUrl = "https://example.com/photo.png",
136+
EmailVerified = true,
137+
Password = "password",
138+
};
139+
140+
var user = await FirebaseAuth.DefaultInstance.CreateUserAsync(args);
141+
142+
try
143+
{
144+
Assert.Equal(randomUser.Uid, user.Uid);
145+
Assert.Equal(randomUser.Email, user.Email);
146+
Assert.Equal(randomUser.PhoneNumber, user.PhoneNumber);
147+
Assert.Equal(args.DisplayName, user.DisplayName);
148+
Assert.Equal(args.PhotoUrl, user.PhotoUrl);
149+
Assert.True(user.EmailVerified);
150+
Assert.False(user.Disabled);
151+
152+
// Cannot recreate the same user.
153+
await Assert.ThrowsAsync<FirebaseException>(
154+
async () => await FirebaseAuth.DefaultInstance.CreateUserAsync(args));
155+
}
156+
finally
157+
{
158+
await FirebaseAuth.DefaultInstance.DeleteUserAsync(user.Uid);
159+
}
160+
}
161+
162+
[Fact]
163+
public async Task UserLifecycle()
164+
{
165+
// Create user
166+
var user = await FirebaseAuth.DefaultInstance.CreateUserAsync(new UserRecordArgs());
167+
var uid = user.Uid;
168+
try
169+
{
170+
Assert.Null(user.Email);
171+
Assert.Null(user.PhoneNumber);
172+
Assert.Null(user.DisplayName);
173+
Assert.Null(user.PhotoUrl);
174+
Assert.False(user.EmailVerified);
175+
Assert.False(user.Disabled);
176+
Assert.NotNull(user.UserMetaData.CreationTimestamp);
177+
Assert.Null(user.UserMetaData.LastSignInTimestamp);
178+
Assert.Empty(user.ProviderData);
179+
Assert.Empty(user.CustomClaims);
180+
181+
// Get user by ID
182+
user = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
183+
Assert.Equal(uid, user.Uid);
184+
Assert.Null(user.Email);
185+
Assert.Null(user.PhoneNumber);
186+
Assert.Null(user.DisplayName);
187+
Assert.Null(user.PhotoUrl);
188+
Assert.False(user.EmailVerified);
189+
Assert.False(user.Disabled);
190+
Assert.NotNull(user.UserMetaData.CreationTimestamp);
191+
Assert.Null(user.UserMetaData.LastSignInTimestamp);
192+
Assert.Empty(user.ProviderData);
193+
Assert.Empty(user.CustomClaims);
194+
195+
// Update user
196+
var randomUser = RandomUser.Create();
197+
var updateArgs = new UserRecordArgs()
198+
{
199+
Uid = uid,
200+
DisplayName = "Updated Name",
201+
Email = randomUser.Email,
202+
PhoneNumber = randomUser.PhoneNumber,
203+
PhotoUrl = "https://example.com/photo.png",
204+
EmailVerified = true,
205+
Password = "secret",
206+
};
207+
user = await FirebaseAuth.DefaultInstance.UpdateUserAsync(updateArgs);
208+
Assert.Equal(uid, user.Uid);
209+
Assert.Equal(randomUser.Email, user.Email);
210+
Assert.Equal(randomUser.PhoneNumber, user.PhoneNumber);
211+
Assert.Equal("Updated Name", user.DisplayName);
212+
Assert.Equal("https://example.com/photo.png", user.PhotoUrl);
213+
Assert.True(user.EmailVerified);
214+
Assert.False(user.Disabled);
215+
Assert.NotNull(user.UserMetaData.CreationTimestamp);
216+
Assert.Null(user.UserMetaData.LastSignInTimestamp);
217+
Assert.Equal(2, user.ProviderData.Length);
218+
Assert.Empty(user.CustomClaims);
219+
220+
// Get user by email
221+
user = await FirebaseAuth.DefaultInstance.GetUserByEmailAsync(randomUser.Email);
222+
Assert.Equal(uid, user.Uid);
223+
224+
// Disable user and remove properties
225+
var disableArgs = new UserRecordArgs()
226+
{
227+
Uid = uid,
228+
Disabled = true,
229+
DisplayName = null,
230+
PhoneNumber = null,
231+
PhotoUrl = null,
232+
};
233+
user = await FirebaseAuth.DefaultInstance.UpdateUserAsync(disableArgs);
234+
Assert.Equal(uid, user.Uid);
235+
Assert.Equal(randomUser.Email, user.Email);
236+
Assert.Null(user.PhoneNumber);
237+
Assert.Null(user.DisplayName);
238+
Assert.Null(user.PhotoUrl);
239+
Assert.True(user.EmailVerified);
240+
Assert.True(user.Disabled);
241+
Assert.NotNull(user.UserMetaData.CreationTimestamp);
242+
Assert.Null(user.UserMetaData.LastSignInTimestamp);
243+
Assert.Single(user.ProviderData);
244+
Assert.Empty(user.CustomClaims);
245+
}
246+
finally
247+
{
248+
// Delete user
249+
await FirebaseAuth.DefaultInstance.DeleteUserAsync(uid);
250+
await Assert.ThrowsAsync<FirebaseException>(
251+
async () => await FirebaseAuth.DefaultInstance.GetUserAsync(uid));
252+
}
253+
}
254+
255+
[Fact]
256+
public async Task GetUserNonExistingUid()
257+
{
258+
await Assert.ThrowsAsync<FirebaseException>(
259+
async () => await FirebaseAuth.DefaultInstance.GetUserAsync("non.existing"));
260+
}
261+
262+
[Fact]
263+
public async Task GetUserNonExistingEmail()
264+
{
265+
await Assert.ThrowsAsync<FirebaseException>(
266+
async () => await FirebaseAuth.DefaultInstance.GetUserByEmailAsync("[email protected]"));
267+
}
268+
269+
[Fact]
270+
public async Task UpdateUserNonExistingUid()
271+
{
272+
var args = new UserRecordArgs()
273+
{
274+
Uid = "non.existing",
275+
};
276+
await Assert.ThrowsAsync<FirebaseException>(
277+
async () => await FirebaseAuth.DefaultInstance.UpdateUserAsync(args));
278+
}
279+
280+
[Fact]
281+
public async Task DeleteUserNonExistingUid()
282+
{
283+
await Assert.ThrowsAsync<FirebaseException>(
284+
async () => await FirebaseAuth.DefaultInstance.DeleteUserAsync("non.existing"));
123285
}
124286

125287
private static async Task<string> SignInWithCustomTokenAsync(string customToken)
@@ -163,4 +325,33 @@ internal class SignInResponse
163325
[Newtonsoft.Json.JsonProperty("idToken")]
164326
public string IdToken { get; set; }
165327
}
328+
329+
internal class RandomUser
330+
{
331+
internal string Uid { get; private set; }
332+
333+
internal string Email { get; private set; }
334+
335+
internal string PhoneNumber { get; private set; }
336+
337+
internal static RandomUser Create()
338+
{
339+
var uid = Guid.NewGuid().ToString().Replace("-", string.Empty);
340+
var email = $"test{uid.Substring(0, 12)}@example.{uid.Substring(12)}.com";
341+
342+
var phone = "+1";
343+
var rand = new Random();
344+
for (int i = 0; i < 10; i++)
345+
{
346+
phone += rand.Next(10);
347+
}
348+
349+
return new RandomUser()
350+
{
351+
Uid = uid,
352+
Email = email,
353+
PhoneNumber = phone,
354+
};
355+
}
356+
}
166357
}

FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAuthSnippets.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,75 @@ internal static async Task VeridyIdTokenAsync(string idToken)
5757
// [END verify_id_token]
5858
Console.WriteLine("Decoded ID token from user: {0}", uid);
5959
}
60+
61+
internal static async Task GetUserAsync(string uid)
62+
{
63+
// [START get_user_by_id]
64+
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
65+
// See the UserRecord reference doc for the contents of userRecord.
66+
Console.WriteLine("Successfully fetched user data: {0}", userRecord.Uid);
67+
// [END get_user_by_id]
68+
}
69+
70+
internal static async Task GetUserByEmailAsync(string email)
71+
{
72+
// [START get_user_by_email]
73+
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserByEmailAsync(email);
74+
// See the UserRecord reference doc for the contents of userRecord.
75+
Console.WriteLine("Successfully fetched user data: {0}", userRecord.Uid);
76+
// [END get_user_by_email]
77+
}
78+
79+
internal static async Task GetUserByPhoneNumberAsync(string phoneNumber)
80+
{
81+
// [START get_user_by_phone]
82+
UserRecord userRecord = await FirebaseAuth.DefaultInstance.GetUserByPhoneNumberAsync(phoneNumber);
83+
// See the UserRecord reference doc for the contents of userRecord.
84+
Console.WriteLine("Successfully fetched user data: {0}", userRecord.Uid);
85+
// [END get_user_by_phone]
86+
}
87+
88+
internal static async Task DeleteUserAsync(string uid)
89+
{
90+
// [START delete_user]
91+
await FirebaseAuth.DefaultInstance.DeleteUserAsync(uid);
92+
Console.WriteLine("Successfully deleted user.");
93+
// [END delete_user]
94+
}
95+
96+
internal static async Task SetCustomUserClaimsAsync(string uid)
97+
{
98+
// [START set_custom_user_claims]
99+
// Set admin privileges on the user corresponding to uid.
100+
var claims = new Dictionary<string, object>()
101+
{
102+
{ "admin", true },
103+
};
104+
await FirebaseAuth.DefaultInstance.SetCustomUserClaimsAsync(uid, claims);
105+
// The new custom claims will propagate to the user's ID token the
106+
// next time a new one is issued.
107+
// [END set_custom_user_claims]
108+
109+
var idToken = "id_token";
110+
// [START verify_custom_claims]
111+
// Verify the ID token first.
112+
FirebaseToken decoded = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
113+
object isAdmin;
114+
if (decoded.Claims.TryGetValue("admin", out isAdmin))
115+
{
116+
if ((bool)isAdmin)
117+
{
118+
// Allow access to requested admin resource.
119+
}
120+
}
121+
122+
// [END verify_custom_claims]
123+
124+
// [START read_custom_user_claims]
125+
// Lookup the user associated with the specified uid.
126+
UserRecord user = await FirebaseAuth.DefaultInstance.GetUserAsync(uid);
127+
Console.WriteLine(user.CustomClaims["admin"]);
128+
// [END read_custom_user_claims]
129+
}
60130
}
61131
}

0 commit comments

Comments
 (0)