@@ -27,7 +27,10 @@ namespace FirebaseAdmin.Auth
2727 /// </summary>
2828 public sealed class UserRecord : IUserInfo
2929 {
30- private const string PROVIDERID = "firebase" ;
30+ internal static readonly DateTime UnixEpoch = new DateTime (
31+ 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
32+
33+ private const string DefaultProviderId = "firebase" ;
3134
3235 private string uid ;
3336 private string email ;
@@ -36,8 +39,8 @@ public sealed class UserRecord : IUserInfo
3639 private string displayName ;
3740 private string photoUrl ;
3841 private bool disabled ;
39- private List < ProviderUserInfo > providers ;
40- private long tokensValidAfterTimestamp ;
42+ private IUserInfo [ ] providers ;
43+ private long validSinceTimestampInSeconds ;
4144 private UserMetadata userMetaData ;
4245 private IReadOnlyDictionary < string , object > customClaims ;
4346
@@ -80,20 +83,19 @@ internal UserRecord(GetAccountInfoResponse.User user)
8083
8184 if ( user . Providers == null || user . Providers . Count == 0 )
8285 {
83- this . providers = new List < ProviderUserInfo > ( ) ;
86+ this . providers = new IUserInfo [ 0 ] ;
8487 }
8588 else
8689 {
8790 var count = user . Providers . Count ;
88- this . providers = new List < ProviderUserInfo > ( count ) ;
89-
91+ this . providers = new IUserInfo [ count ] ;
9092 for ( int i = 0 ; i < count ; i ++ )
9193 {
92- this . providers . Add ( new ProviderUserInfo ( user . Providers [ i ] ) ) ;
94+ this . providers [ i ] = new ProviderUserInfo ( user . Providers [ i ] ) ;
9395 }
9496 }
9597
96- this . tokensValidAfterTimestamp = user . ValidSince * 1000 ;
98+ this . validSinceTimestampInSeconds = user . ValidSince ;
9799 this . userMetaData = new UserMetadata ( user . CreatedAt , user . LastLoginAt ) ;
98100 this . customClaims = UserRecord . ParseCustomClaims ( user . CustomClaims ) ;
99101 }
@@ -112,49 +114,43 @@ private set
112114 }
113115
114116 /// <summary>
115- /// Gets the user's display name, if available.
117+ /// Gets the user's display name, if available. Otherwise null.
116118 /// </summary>
117- /// <returns>a display name string or null.</returns>
118119 public string DisplayName
119120 {
120121 get => this . displayName ;
121122 }
122123
123124 /// <summary>
124- /// Gets the user's email address, if available.
125+ /// Gets the user's email address, if available. Otherwise null.
125126 /// </summary>
126- /// <returns>an email address string or null.</returns>
127127 public string Email
128128 {
129129 get => this . email ;
130130 }
131131
132132 /// <summary>
133- /// Gets the user's phone number.
133+ /// Gets the user's phone number, if available. Otherwise null .
134134 /// </summary>
135- /// <returns>a phone number string or null.</returns>
136135 public string PhoneNumber
137136 {
138137 get => this . phoneNumber ;
139138 }
140139
141140 /// <summary>
142- /// Gets the user's photo URL, if available.
141+ /// Gets the user's photo URL, if available. Otherwise null.
143142 /// </summary>
144- /// <returns>a URL string or null.</returns>
145143 public string PhotoUrl
146144 {
147145 get => this . photoUrl ;
148146 }
149147
150148 /// <summary>
151- /// Gets the ID of the identity provider. This can be a short domain name (e.g. google.com) or
152- /// the identifier of an OpenID identity provider.
149+ /// Gets the ID of the identity provider. This has the constant value <c>firebase</c>.
153150 /// </summary>
154- /// <returns>an ID string that uniquely identifies the identity provider.</returns>
155151 public string ProviderId
156152 {
157- get => UserRecord . PROVIDERID ;
153+ get => UserRecord . DefaultProviderId ;
158154 }
159155
160156 /// <summary>
@@ -168,28 +164,36 @@ public string ProviderId
168164 public bool Disabled => this . disabled ;
169165
170166 /// <summary>
171- /// Gets a list of provider data for this user.
167+ /// Gets a non-null array of provider data for this user. Possibly empty .
172168 /// </summary>
173- public IEnumerable < IUserInfo > Providers => this . providers ;
169+ public IUserInfo [ ] ProviderData => this . providers ;
174170
175171 /// <summary>
176- /// Gets a timestamp representing the date and time that this token will become active.
172+ /// Gets a timestamp that indicates the earliest point in time at which a valid ID token
173+ /// could have been issued to this user. Tokens issued prior to this timestamp are
174+ /// considered invalid.
177175 /// </summary>
178- public long TokensValidAfterTimestamp => this . tokensValidAfterTimestamp ;
176+ public DateTime TokensValidAfterTimestamp
177+ {
178+ get
179+ {
180+ return UnixEpoch . AddSeconds ( this . validSinceTimestampInSeconds ) ;
181+ }
182+ }
179183
180184 /// <summary>
181185 /// Gets additional user metadata.
182186 /// </summary>
183187 public UserMetadata UserMetaData => this . userMetaData ;
184188
185189 /// <summary>
186- /// Gets or sets the custom claims set on this user.
190+ /// Gets the custom claims set on this user.
187191 /// </summary>
188192 [ JsonIgnore ]
189193 public IReadOnlyDictionary < string , object > CustomClaims
190194 {
191195 get => this . customClaims ;
192- set
196+ internal set
193197 {
194198 CheckCustomClaims ( value ) ;
195199 this . customClaims = value ;
@@ -204,7 +208,7 @@ public IReadOnlyDictionary<string, object> CustomClaims
204208 /// </summary>
205209 /// <param name="uid">The user ID. Must not be null or longer than
206210 /// 128 characters.</param>
207- public static void CheckUid ( string uid )
211+ private static void CheckUid ( string uid )
208212 {
209213 if ( string . IsNullOrEmpty ( uid ) )
210214 {
@@ -222,7 +226,7 @@ public static void CheckUid(string uid)
222226 /// <param name="customClaims">The custom claims. Claim names must
223227 /// not be null or empty and must not be reserved and the serialized
224228 /// claims have to be less than 1000 bytes.</param>
225- internal static void CheckCustomClaims ( IReadOnlyDictionary < string , object > customClaims )
229+ private static void CheckCustomClaims ( IReadOnlyDictionary < string , object > customClaims )
226230 {
227231 if ( customClaims == null )
228232 {
0 commit comments