Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
8 changes: 8 additions & 0 deletions packages/firebase_auth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.13.0

* **Breaking change**: Replace `FirebaseUserMetadata.creationTimestamp` and
`FirebaseUserMetadata.lastSignInTimestamp` with `creationTime` and `lastSignInTime`.
Previously on iOS `creationTimestamp` and `lastSignInTimestamp` returned in
seconds and on Android in milliseconds. Now, both platforms provide values as a
`DateTime`.

## 0.12.0+1

* Fixes iOS sign-in exceptions when `additionalUserInfo` is `nil` or has `nil` fields.
Expand Down
16 changes: 13 additions & 3 deletions packages/firebase_auth/example/test/firebase_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:firebase_auth/firebase_auth.dart';

void main() {
final Completer<String> completer = Completer<String>();
Expand All @@ -22,8 +23,6 @@ void main() {
test('signInAnonymously', () async {
final AuthResult result = await auth.signInAnonymously();
final FirebaseUser user = result.user;
expect(user.uid, isNotNull);
expect(user.isAnonymous, isTrue);
final AdditionalUserInfo additionalUserInfo = result.additionalUserInfo;
expect(additionalUserInfo.username, isNull);
expect(additionalUserInfo.isNewUser, isNotNull);
Expand All @@ -34,6 +33,17 @@ void main() {
additionalUserInfo.providerId == null ||
additionalUserInfo.providerId == 'password',
isTrue);
expect(user.uid, isNotNull);
expect(user.isAnonymous, isTrue);
expect(user.metadata.creationTime.isAfter(DateTime(2018, 1, 1)), isTrue);
expect(user.metadata.creationTime.isBefore(DateTime.now()), isTrue);
await auth.signOut();
final FirebaseUser user2 = (await auth.signInAnonymously()).user;
expect(user2.uid, isNot(equals(user.uid)));
expect(user2.metadata.creationTime.isBefore(user.metadata.creationTime),
isFalse);
expect(
user2.metadata.lastSignInTime, equals(user2.metadata.creationTime));
});

test('isSignInWithEmailLink', () async {
Expand Down
4 changes: 2 additions & 2 deletions packages/firebase_auth/ios/Classes/FirebaseAuthPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,8 @@ - (NSMutableDictionary *)dictionaryFromUser:(FIRUser *)user {
[providerData addObject:toDictionary(userInfo)];
}

long creationDate = [user.metadata.creationDate timeIntervalSince1970];
long lastSignInDate = [user.metadata.lastSignInDate timeIntervalSince1970];
long creationDate = [user.metadata.creationDate timeIntervalSince1970] * 1000;
long lastSignInDate = [user.metadata.lastSignInDate timeIntervalSince1970] * 1000;

NSMutableDictionary *userData = [toDictionary(user) mutableCopy];
userData[@"creationTimestamp"] = [NSNumber numberWithLong:creationDate];
Expand Down
10 changes: 8 additions & 2 deletions packages/firebase_auth/lib/src/user_metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ class FirebaseUserMetadata {

final Map<String, dynamic> _data;

int get creationTimestamp => _data['creationTimestamp'];
/// When this account was created as dictated by the server clock.
DateTime get creationTime =>
DateTime.fromMillisecondsSinceEpoch(_data['creationTimestamp']);

int get lastSignInTimestamp => _data['lastSignInTimestamp'];
/// When the user last signed in as dictated by the server clock.
///
/// This is only accurate up to a granularity of 2 minutes for consecutive sign-in attempts.
DateTime get lastSignInTime =>
DateTime.fromMillisecondsSinceEpoch(_data['lastSignInTimestamp']);
}
2 changes: 1 addition & 1 deletion packages/firebase_auth/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Flutter plugin for Firebase Auth, enabling Android and iOS
like Google, Facebook and Twitter.
author: Flutter Team <[email protected]>
homepage: https://github.com/flutter/plugins/tree/master/packages/firebase_auth
version: "0.12.0+1"
version: 0.13.0

flutter:
plugin:
Expand Down
23 changes: 16 additions & 7 deletions packages/firebase_auth/test/firebase_auth_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,14 @@ const String kMockPhoneNumber = '5555555555';
const String kMockVerificationId = '12345';
const String kMockSmsCode = '123456';
const String kMockLanguage = 'en';
const Map<String, dynamic> kMockAdditionalUserInfo = <String, dynamic>{
'isNewUser': false,
'username': 'flutterUser',
'providerId': 'testProvider',
'profile': <String, dynamic>{'foo': 'bar'},
};
const Map<String, dynamic> kMockUser = <String, dynamic>{
final int kMockCreationTimestamp = DateTime(2019, 1, 1).millisecondsSinceEpoch;
final int kMockLastSignInTimestamp =
DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch;
final Map<String, dynamic> kMockUser = <String, dynamic>{
'isAnonymous': true,
'isEmailVerified': false,
'creationTimestamp': kMockCreationTimestamp,
'lastSignInTimestamp': kMockLastSignInTimestamp,
'providerData': <Map<String, String>>[
<String, String>{
'providerId': kMockProviderId,
Expand All @@ -44,6 +43,12 @@ const Map<String, dynamic> kMockUser = <String, dynamic>{
},
],
};
const Map<String, dynamic> kMockAdditionalUserInfo = <String, dynamic>{
'isNewUser': false,
'username': 'flutterUser',
'providerId': 'testProvider',
'profile': <String, dynamic>{'foo': 'bar'},
};

void main() {
group('$FirebaseAuth', () {
Expand Down Expand Up @@ -103,6 +108,10 @@ void main() {
expect(userInfo.displayName, kMockDisplayName);
expect(userInfo.photoUrl, kMockPhotoUrl);
expect(userInfo.email, kMockEmail);
expect(user.metadata.creationTime.millisecondsSinceEpoch,
kMockCreationTimestamp);
expect(user.metadata.lastSignInTime.millisecondsSinceEpoch,
kMockLastSignInTimestamp);
}

void verifyAuthResult(AuthResult result) {
Expand Down