Skip to content

Commit 899de97

Browse files
committed
Thread safety
1 parent 328f1a7 commit 899de97

1 file changed

Lines changed: 34 additions & 20 deletions

File tree

CorePush/Firebase/FirebaseSender.cs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class FirebaseSender : IFirebaseSender
2323
private readonly HttpClient http;
2424
private readonly FirebaseSettings settings;
2525
private readonly IJsonSerializer serializer;
26+
private readonly SemaphoreSlim tokenLock = new(1, 1);
2627

2728
private DateTime? firebaseTokenExpiration;
2829
private FirebaseTokenResponse firebaseToken;
@@ -121,30 +122,43 @@ private async Task<string> GetJwtTokenAsync(CancellationToken cancellationToken)
121122
return firebaseToken.AccessToken;
122123
}
123124

124-
using var message = new HttpRequestMessage(HttpMethod.Post, "https://oauth2.googleapis.com/token");
125-
using var form = new MultipartFormDataContent();
126-
var authToken = GetMasterToken();
127-
form.Add(new StringContent(authToken), "assertion");
128-
form.Add(new StringContent("urn:ietf:params:oauth:grant-type:jwt-bearer"), "grant_type");
129-
message.Content = form;
130-
131-
using var response = await http.SendAsync(message, cancellationToken);
132-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
133-
134-
if (!response.IsSuccessStatusCode)
125+
await tokenLock.WaitAsync(cancellationToken);
126+
try
135127
{
136-
throw new HttpRequestException("Firebase error when creating JWT token: " + content);
137-
}
128+
if (firebaseToken != null && firebaseTokenExpiration > DateTime.UtcNow)
129+
{
130+
return firebaseToken.AccessToken;
131+
}
132+
133+
using var message = new HttpRequestMessage(HttpMethod.Post, "https://oauth2.googleapis.com/token");
134+
using var form = new MultipartFormDataContent();
135+
var authToken = GetMasterToken();
136+
form.Add(new StringContent(authToken), "assertion");
137+
form.Add(new StringContent("urn:ietf:params:oauth:grant-type:jwt-bearer"), "grant_type");
138+
message.Content = form;
139+
140+
using var response = await http.SendAsync(message, cancellationToken);
141+
var content = await response.Content.ReadAsStringAsync(cancellationToken);
142+
143+
if (!response.IsSuccessStatusCode)
144+
{
145+
throw new HttpRequestException("Firebase error when creating JWT token: " + content);
146+
}
147+
148+
firebaseToken = serializer.Deserialize<FirebaseTokenResponse>(content);
149+
firebaseTokenExpiration = DateTime.UtcNow.AddSeconds(firebaseToken.ExpiresIn - 10);
150+
151+
if (string.IsNullOrWhiteSpace(firebaseToken.AccessToken) || firebaseTokenExpiration < DateTime.UtcNow)
152+
{
153+
throw new InvalidOperationException("Couldn't deserialize firebase token response");
154+
}
138155

139-
firebaseToken = serializer.Deserialize<FirebaseTokenResponse>(content);
140-
firebaseTokenExpiration = DateTime.UtcNow.AddSeconds(firebaseToken.ExpiresIn - 10);
141-
142-
if (string.IsNullOrWhiteSpace(firebaseToken.AccessToken) || firebaseTokenExpiration < DateTime.UtcNow)
156+
return firebaseToken.AccessToken;
157+
}
158+
finally
143159
{
144-
throw new InvalidOperationException("Couldn't deserialize firebase token response");
160+
tokenLock.Release();
145161
}
146-
147-
return firebaseToken.AccessToken;
148162
}
149163

150164
private string GetMasterToken()

0 commit comments

Comments
 (0)