firebase-admin-dotnet
firebase-admin-dotnet copied to clipboard
Errors while importing users from the output of ListUsersAsync
Hi, I am trying to implement the export and import function with C# FirebaseAdmin 3.0.0 with .NET8.0. I am currently facing two issues. I don't know if it belongs to a bug so I could not find a suitable issue type. Please let me know if there is any information missed.
- I try to export users with ListUsersAsync and save deserialised ExportedUserRecord objects to a file
var users = new List<ExportedUserRecord>();
var pagedEnumerable = firebaseAuth.ListUsersAsync(null);
await foreach (var user in pagedEnumerable)
{
users.Add(user);
}
var json = JsonSerializer.Serialize(users); // save this to a file
- When I try to seralise the file back to
ImportUserRecordArgs
,UserMetadata
field andUserProviders
filed are always null because the fields name inExportedUserRecord
areUserMetaData
andProviderData
. So some custom json converts will be required
Here is the converter I write to solve the problem for UserMetaData
public class UserMetadataConverter : JsonConverter<UserMetadata>
{
public override UserMetadata Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
long creationTimestampMillis = 0;
long lastSignInTimestampMillis = 0;
DateTime? lastRefreshTimestamp = null;
var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return new UserMetadata(creationTimestampMillis, lastSignInTimestampMillis, lastRefreshTimestamp);
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propertyName = reader.GetString() ?? string.Empty;
reader.Read();
switch (propertyName)
{
case "CreationTimestamp":
creationTimestampMillis = (long)(reader.GetDateTime() - unixEpoch).TotalMilliseconds;
break;
case "LastSignInTimestamp":
lastSignInTimestampMillis = (long)(reader.GetDateTime() - unixEpoch).TotalMilliseconds;
break;
case "LastRefreshTimestamp":
lastRefreshTimestamp = reader.TokenType == JsonTokenType.Null ? null : reader.GetDateTime();
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, UserMetadata value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("CreationTimestamp", value.CreationTimestamp.ToString());
writer.WriteString("LastSignInTimestamp", value.LastSignInTimestamp.ToString());
writer.WriteString("LastRefreshTimestamp", value.LastRefreshTimestamp.ToString());
writer.WriteEndObject();
}
}
- After deserialising the json file to ImportUserRecordArgs objects,
firebaseAuth.ImportUsersAsync
throws errors like following
{
"field": "users[0].created_at",
"description": "Invalid value at 'users[0].created_at' (TYPE_INT64), \"2024-06-03T02:53:37.173Z\""
},
{
"field": "users[0].last_login_at",
"description": "Invalid value at 'users[0].last_login_at' (TYPE_INT64), \"2024-06-03T02:53:37.173Z\""
},
Error comes from
at FirebaseAdmin.Util.ErrorHandlingHttpClient`1.SendAndReadAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at FirebaseAdmin.Util.ErrorHandlingHttpClient`1.SendAndDeserializeAsync[TResult](HttpRequestMessage request, CancellationToken cancellationToken)
at FirebaseAdmin.Auth.Users.FirebaseUserManager.PostAndDeserializeAsync[TResult](String path, Object body, CancellationToken cancellationToken)
at FirebaseAdmin.Auth.Users.FirebaseUserManager.ImportUsersAsync(IEnumerable`1 users, UserImportOptions options, CancellationToken cancellationToken)
at FirebaseAdmin.Auth.AbstractFirebaseAuth.ImportUsersAsync(IEnumerable`1 users, UserImportOptions options, CancellationToken cancellationToken)
Here is an example of the ImportUserRecordArg
object
{FirebaseAdmin.Auth.ImportUserRecordArgs}
CustomClaims: Count = 0
Disabled: false
DisplayName: null
Email: null
EmailVerified: false
PasswordHash: null
PasswordSalt: null
PhoneNumber: null
PhotoUrl: null
Uid: "abcdefg...example"
UserMetadata: {FirebaseAdmin.Auth.UserMetadata}
UserProviders: null
Here is the example of the UserMetadata object
{FirebaseAdmin.Auth.UserMetadata}
CreationTimestamp: {03/06/2024 02:53:37}
LastRefreshTimestamp: null
LastSignInTimestamp: {03/06/2024 02:53:37}
Not sure if the above behaviours are expected?
Thank you