firebase / firebase/firebase-admin-dotnet

Errors while importing users from the output of ListUsersAsync

Open
#419 1 comment 0 reactions 0 assignees View on GitHub
needs-triage
Dominant language
C#
Stars
408
Forks
146
Avg merge
22h 7m
Merged PRs (30d)
1

Description

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.

1. I try to export users with ListUsersAsync and save deserialised ExportedUserRecord objects to a file

```
var users = new List();
var pagedEnumerable = firebaseAuth.ListUsersAsync(null);
await foreach (var user in pagedEnumerable)
{
users.Add(user);
}

var json = JsonSerializer.Serialize(users); // save this to a file
```

2. When I try to seralise the file back to `ImportUserRecordArgs`, `UserMetadata` field and `UserProviders` filed are always null because the fields name in `ExportedUserRecord` are `UserMetaData` and `ProviderData`. So some custom json converts will be required

Here is the converter I write to solve the problem for UserMetaData

```
public class UserMetadataConverter : JsonConverter
{
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();
}
}
```

3. 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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.