Skip to content

Commit c932fe7

Browse files
replaced the PagedEnumerable by RestPagedAsyncEnumerable
1 parent ff90d61 commit c932fe7

File tree

10 files changed

+221
-136
lines changed

10 files changed

+221
-136
lines changed

FirebaseAdmin/FirebaseAdmin.IntegrationTests/FirebaseAdmin.IntegrationTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Google.Apis.Auth" Version="1.35.1" />
11+
<PackageReference Include="Google.Apis.Auth" Version="1.40.0" />
1212
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
1313
<PackageReference Include="xunit" Version="2.3.1" />
1414
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />

FirebaseAdmin/FirebaseAdmin.Snippets/FirebaseAdmin.Snippets.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Google.Apis.Auth" Version="1.35.1" />
11+
<PackageReference Include="Google.Apis.Auth" Version="1.40.0" />
1212
</ItemGroup>
1313

1414
<ItemGroup>

FirebaseAdmin/FirebaseAdmin.Tests/FirebaseAdmin.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Google.Apis.Auth" Version="1.35.1" />
13+
<PackageReference Include="Google.Apis.Auth" Version="1.40.0" />
1414
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
1515
<PackageReference Include="xunit" Version="2.3.1" />
1616
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseAuth.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Threading;
1818
using System.Threading.Tasks;
1919
using Google.Api.Gax;
20+
using Google.Api.Gax.Rest;
2021

2122
namespace FirebaseAdmin.Auth
2223
{
@@ -348,15 +349,20 @@ public async Task SetCustomUserClaimsAsync(
348349
}
349350

350351
/// <summary>
351-
/// Gets a page of users starting from the specified pageToken. Page size will be limited to 1000 users.
352+
/// Gets an async enumerable to page users starting from the specified pageToken. If the pageToken is empty, it starts from the first page.
352353
/// </summary>
353-
/// <param name="cancellationToken">A cancellation token to monitor the asynchronous operation.</param>
354-
/// <returns>A <see cref="UserList"/> instance.</returns>
355-
public PagedEnumerable<DownloadAccountResponse, UserRecord> ListUsersAsync(CancellationToken cancellationToken = default(CancellationToken))
354+
/// <param name="pageToken">The page token for the next remote call.</param>
355+
/// <returns>A <see cref="PagedAsyncEnumerable{DownloadAccountResponse, UserRecord}"/> instance.</returns>
356+
public PagedAsyncEnumerable<DownloadAccountResponse, UserRecord> ListUsersAsync(string pageToken)
356357
{
357358
var userManager = this.IfNotDeleted(() => this.userManager.Value);
359+
var requestOptions = new UserRecordServiceRequest.UserRecordServiceRequestOptions() { NextPageToken = pageToken };
358360

359-
return new UserList(UserSource.DefaultUserSource(userManager, cancellationToken));
361+
var restPagedAsyncEnumerable = new RestPagedAsyncEnumerable<UserRecordServiceRequest, DownloadAccountResponse, UserRecord>(
362+
() => userManager.CreateUserRecordServiceRequest(requestOptions),
363+
new UserRecordPageManager());
364+
365+
return restPagedAsyncEnumerable;
360366
}
361367

362368
/// <summary>

FirebaseAdmin/FirebaseAdmin/Auth/FirebaseUserManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public async Task<UserRecord> GetUserById(
100100
return new UserRecord(user);
101101
}
102102

103+
public UserRecordServiceRequest CreateUserRecordServiceRequest(UserRecordServiceRequest.UserRecordServiceRequestOptions requestOptions)
104+
{
105+
return new UserRecordServiceRequest(this.baseUrl, this.httpClient, requestOptions);
106+
}
107+
103108
/// <summary>
104109
/// Gets a page of users starting from the specified <paramref name="pageToken"/>. Page size will be limited to <paramref name="maxResults"/> users.
105110
/// </summary>

FirebaseAdmin/FirebaseAdmin/Auth/UserList.cs

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Collections.Generic;
2+
using Google.Api.Gax.Rest;
3+
4+
namespace FirebaseAdmin.Auth
5+
{
6+
internal class UserRecordPageManager : IPageManager<UserRecordServiceRequest, DownloadAccountResponse, UserRecord>
7+
{
8+
public void SetPageSize(UserRecordServiceRequest request, int pageSize)
9+
{
10+
request.SetPageSize(pageSize);
11+
}
12+
13+
public void SetPageToken(UserRecordServiceRequest request, string pageToken)
14+
{
15+
request.SetPageToken(pageToken);
16+
}
17+
18+
public IEnumerable<UserRecord> GetResources(DownloadAccountResponse response)
19+
{
20+
if (response?.Users == null)
21+
{
22+
yield break;
23+
}
24+
25+
foreach (var user in response.Users)
26+
{
27+
yield return new UserRecord(user);
28+
}
29+
}
30+
31+
public string GetNextPageToken(DownloadAccountResponse response)
32+
{
33+
return string.IsNullOrEmpty(response.NextPageToken) ? null : response.NextPageToken;
34+
}
35+
}
36+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Net.Http;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Google.Apis.Discovery;
9+
using Google.Apis.Json;
10+
using Google.Apis.Requests;
11+
using Google.Apis.Services;
12+
13+
namespace FirebaseAdmin.Auth
14+
{
15+
internal class UserRecordServiceRequest : IClientServiceRequest<DownloadAccountResponse>
16+
{
17+
private readonly string baseUrl;
18+
private readonly HttpClient httpClient;
19+
private readonly UserRecordServiceRequestOptions requestOptions;
20+
21+
internal UserRecordServiceRequest(string baseUrl, HttpClient httpClient, UserRecordServiceRequestOptions requestOptions)
22+
{
23+
this.baseUrl = baseUrl;
24+
this.httpClient = httpClient;
25+
this.requestOptions = requestOptions;
26+
this.RequestParameters = new Dictionary<string, IParameter>();
27+
28+
// this is the default page-size if no other value is set.
29+
this.SetPageSize(FirebaseUserManager.MaxListUsersResults);
30+
this.SetPageToken(requestOptions.NextPageToken);
31+
}
32+
33+
public string MethodName => "ListUsers";
34+
35+
public string RestPath => "accounts:batchGet";
36+
37+
public string HttpMethod => "GET";
38+
39+
public IDictionary<string, IParameter> RequestParameters { get; private set; }
40+
41+
public IClientService Service { get; }
42+
43+
public void SetPageSize(int pageSize)
44+
{
45+
this.AddOrUpdate("maxResults", pageSize.ToString());
46+
}
47+
48+
public void SetPageToken(string pageToken)
49+
{
50+
this.AddOrUpdate("nextPageToken", pageToken);
51+
this.requestOptions.NextPageToken = pageToken;
52+
}
53+
54+
public HttpRequestMessage CreateRequest(bool? overrideGZipEnabled = null)
55+
{
56+
var queryParameters = string.Join("&", this.RequestParameters.Select(kvp => $"{kvp.Key}={kvp.Value.DefaultValue}"));
57+
58+
var request = new HttpRequestMessage()
59+
{
60+
Method = System.Net.Http.HttpMethod.Get,
61+
RequestUri = new Uri($"{this.baseUrl}/{this.RestPath}?{queryParameters}"),
62+
};
63+
64+
return request;
65+
}
66+
67+
public Task<Stream> ExecuteAsStreamAsync()
68+
{
69+
return this.ExecuteAsStreamAsync(default);
70+
}
71+
72+
public Task<Stream> ExecuteAsStreamAsync(CancellationToken cancellationToken)
73+
{
74+
var response = this.SendAsync(this.CreateRequest(), cancellationToken);
75+
return response.Result.Content.ReadAsStreamAsync();
76+
}
77+
78+
public Stream ExecuteAsStream()
79+
{
80+
return this.ExecuteAsStreamAsync().Result;
81+
}
82+
83+
public Task<DownloadAccountResponse> ExecuteAsync()
84+
{
85+
return this.ExecuteAsync(default);
86+
}
87+
88+
public Task<DownloadAccountResponse> ExecuteAsync(CancellationToken cancellationToken)
89+
{
90+
return this.SendAndDeserializeAsync<DownloadAccountResponse>(this.CreateRequest(), cancellationToken);
91+
}
92+
93+
public DownloadAccountResponse Execute()
94+
{
95+
return this.ExecuteAsync().Result;
96+
}
97+
98+
private async Task<TResult> SendAndDeserializeAsync<TResult>(HttpRequestMessage request, CancellationToken cancellationToken)
99+
{
100+
var response = await this.SendAsync(request, cancellationToken).ConfigureAwait(false);
101+
102+
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
103+
if (!response.IsSuccessStatusCode)
104+
{
105+
var error = "Response status code does not indicate success: "
106+
+ $"{(int)response.StatusCode} ({response.StatusCode})"
107+
+ $"{Environment.NewLine}{json}";
108+
throw new FirebaseException(error);
109+
}
110+
111+
return this.SafeDeserialize<TResult>(json);
112+
}
113+
114+
private async Task<HttpResponseMessage> SendAsync(
115+
HttpRequestMessage request, CancellationToken cancellationToken)
116+
{
117+
try
118+
{
119+
return await this.httpClient.SendAsync(request, cancellationToken)
120+
.ConfigureAwait(false);
121+
}
122+
catch (HttpRequestException e)
123+
{
124+
throw new FirebaseException("Error while calling Firebase Auth service", e);
125+
}
126+
}
127+
128+
private TResult SafeDeserialize<TResult>(string json)
129+
{
130+
try
131+
{
132+
return NewtonsoftJsonSerializer.Instance.Deserialize<TResult>(json);
133+
}
134+
catch (Exception e)
135+
{
136+
throw new FirebaseException("Error while parsing Auth service response", e);
137+
}
138+
}
139+
140+
private void AddOrUpdate(string paramName, string value)
141+
{
142+
var parameter = new Parameter()
143+
{
144+
DefaultValue = value,
145+
IsRequired = true,
146+
Name = paramName,
147+
};
148+
149+
if (!this.RequestParameters.ContainsKey(paramName))
150+
{
151+
this.RequestParameters.Add(paramName, parameter);
152+
}
153+
else
154+
{
155+
this.RequestParameters[paramName] = parameter;
156+
}
157+
}
158+
159+
internal class UserRecordServiceRequestOptions
160+
{
161+
public string NextPageToken { get; set; }
162+
}
163+
}
164+
}

0 commit comments

Comments
 (0)