Skip to content

Commit 1a44ca1

Browse files
authored
Merge pull request #32 from levimatheri/user-workflow
Add get-by-id and delete user
2 parents 6ca2baf + 10d776d commit 1a44ca1

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

FirebaseAdmin/FirebaseAdmin.Tests/Auth/FirebaseUserManagerTest.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,44 @@ public void TooLargeClaimsPayload()
7171
Assert.Throws<ArgumentException>(() => new UserRecord("user1") { CustomClaims = customClaims });
7272
}
7373

74+
[Fact]
75+
public async Task GetUserById()
76+
{
77+
var handler = new MockMessageHandler()
78+
{
79+
Response = new UserRecord("user1"),
80+
};
81+
var factory = new MockHttpClientFactory(handler);
82+
var userManager = new FirebaseUserManager(
83+
new FirebaseUserManagerArgs
84+
{
85+
Credential = MockCredential,
86+
ProjectId = MockProjectId,
87+
ClientFactory = factory,
88+
});
89+
var userRecord = await userManager.GetUserById("user1");
90+
Assert.Equal("user1", userRecord.Uid);
91+
}
92+
93+
[Fact]
94+
public async Task GetUserByIdUserNotFound()
95+
{
96+
var handler = new MockMessageHandler()
97+
{
98+
StatusCode = HttpStatusCode.NotFound,
99+
};
100+
var factory = new MockHttpClientFactory(handler);
101+
var userManager = new FirebaseUserManager(
102+
new FirebaseUserManagerArgs
103+
{
104+
Credential = MockCredential,
105+
ProjectId = MockProjectId,
106+
ClientFactory = factory,
107+
});
108+
await Assert.ThrowsAsync<FirebaseException>(
109+
async () => await userManager.GetUserById("user1"));
110+
}
111+
74112
[Fact]
75113
public async Task UpdateUser()
76114
{
@@ -165,5 +203,45 @@ public async Task UpdateUserHttpError()
165203
await Assert.ThrowsAsync<FirebaseException>(
166204
async () => await userManager.UpdateUserAsync(new UserRecord("user1") { CustomClaims = customClaims }));
167205
}
206+
207+
[Fact]
208+
public async Task DeleteUser()
209+
{
210+
var handler = new MockMessageHandler()
211+
{
212+
Response = new Dictionary<string, string>()
213+
{
214+
{ "kind", "identitytoolkit#DeleteAccountResponse" },
215+
},
216+
};
217+
var factory = new MockHttpClientFactory(handler);
218+
var userManager = new FirebaseUserManager(
219+
new FirebaseUserManagerArgs
220+
{
221+
Credential = MockCredential,
222+
ProjectId = MockProjectId,
223+
ClientFactory = factory,
224+
});
225+
await userManager.DeleteUser("user1");
226+
}
227+
228+
[Fact]
229+
public async Task DeleteUserNotFound()
230+
{
231+
var handler = new MockMessageHandler()
232+
{
233+
StatusCode = HttpStatusCode.NotFound,
234+
};
235+
var factory = new MockHttpClientFactory(handler);
236+
var userManager = new FirebaseUserManager(
237+
new FirebaseUserManagerArgs
238+
{
239+
Credential = MockCredential,
240+
ProjectId = MockProjectId,
241+
ClientFactory = factory,
242+
});
243+
await Assert.ThrowsAsync<FirebaseException>(
244+
async () => await userManager.DeleteUser("user1"));
245+
}
168246
}
169247
}

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
using System;
16+
using System.Collections.Generic;
1617
using System.Net.Http;
1718
using System.Threading;
1819
using System.Threading.Tasks;
@@ -60,6 +61,36 @@ public static FirebaseUserManager Create(FirebaseApp app)
6061
return new FirebaseUserManager(args);
6162
}
6263

64+
/// <summary>
65+
/// Gets the user data corresponding to the given user ID.
66+
/// </summary>
67+
/// <param name="uid">A user ID string.</param>
68+
/// <param name="cancellationToken">A cancellation token to monitor the asynchronous
69+
/// operation.</param>
70+
/// <returns>A record of user with the queried id if one exists.</returns>
71+
public async Task<UserRecord> GetUserById(
72+
string uid, CancellationToken cancellationToken = default(CancellationToken))
73+
{
74+
if (string.IsNullOrEmpty(uid))
75+
{
76+
throw new ArgumentException("User ID cannot be null or empty.");
77+
}
78+
79+
const string getUserPath = "accounts:lookup";
80+
var payload = new Dictionary<string, object>()
81+
{
82+
{ "localId", uid },
83+
};
84+
var response = await this.PostAndDeserializeAsync<JObject>(
85+
getUserPath, payload, cancellationToken).ConfigureAwait(false);
86+
if (response == null || uid != (string)response["localId"])
87+
{
88+
throw new FirebaseException($"Failed to get user: {uid}");
89+
}
90+
91+
return new UserRecord((string)response["localId"]);
92+
}
93+
6394
/// <summary>
6495
/// Update an existing user.
6596
/// </summary>
@@ -79,6 +110,33 @@ public async Task UpdateUserAsync(
79110
}
80111
}
81112

113+
/// <summary>
114+
/// Delete user data corresponding to the given user ID.
115+
/// </summary>
116+
/// <param name="uid">A user ID string.</param>
117+
/// <param name="cancellationToken">A cancellation token to monitor the asynchronous
118+
/// operation.</param>
119+
public async Task DeleteUser(
120+
string uid, CancellationToken cancellationToken = default(CancellationToken))
121+
{
122+
if (string.IsNullOrEmpty(uid))
123+
{
124+
throw new ArgumentException("User id cannot be null or empty.");
125+
}
126+
127+
const string getUserPath = "accounts:delete";
128+
var payload = new Dictionary<string, object>()
129+
{
130+
{ "localId", uid },
131+
};
132+
var response = await this.PostAndDeserializeAsync<JObject>(
133+
getUserPath, payload, cancellationToken).ConfigureAwait(false);
134+
if (response == null || (string)response["kind"] == null)
135+
{
136+
throw new FirebaseException($"Failed to delete user: {uid}");
137+
}
138+
}
139+
82140
public void Dispose()
83141
{
84142
this.httpClient.Dispose();

0 commit comments

Comments
 (0)