Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(firebase_auth): implement support for useEmulator #4263

Merged
merged 3 commits into from
Jan 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .github/workflows/firebase_auth.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
branches:
- master
paths-ignore:
- "docs/**"
- "docs/**"

env:
FLUTTERFIRE_PLUGIN_SCOPE: "*firebase_auth*"
Expand All @@ -27,9 +27,13 @@ jobs:
- name: "Install Flutter"
run: ./.github/workflows/scripts/install-flutter.sh dev
- name: "Install Tools"
run: ./.github/workflows/scripts/install-tools.sh
run: |
./.github/workflows/scripts/install-tools.sh
sudo npm i -g firebase-tools
russellwheatley marked this conversation as resolved.
Show resolved Hide resolved
- name: "Build Example"
run: ./.github/workflows/scripts/build-example.sh android
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
uses: reactivecircus/android-emulator-runner@v2
with:
Expand All @@ -51,9 +55,12 @@ jobs:
- name: "Install Tools"
run: |
./.github/workflows/scripts/install-tools.sh
sudo npm i -g firebase-tools
flutter config --enable-macos-desktop
- name: "Build iOS Example"
run: ./.github/workflows/scripts/build-example.sh ios
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive iOS Example"
run: ./.github/workflows/scripts/drive-example.sh ios
- name: "Build MacOS Example"
Expand All @@ -62,7 +69,9 @@ jobs:
run: ./.github/workflows/scripts/drive-example.sh macos

web:
runs-on: ubuntu-latest
# Using macos instead of ubuntu as Web app can't connect to Firebase emulator
# when running on ubuntu.
runs-on: macos-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v1
Expand All @@ -74,5 +83,8 @@ jobs:
run: |
./.github/workflows/scripts/install-tools.sh
flutter config --enable-web
sudo npm i -g firebase-tools
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
run: ./.github/workflows/scripts/drive-example.sh web
14 changes: 7 additions & 7 deletions .github/workflows/firebase_firestore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ jobs:
sudo npm i -g firebase-tools
- name: "Build Example"
run: ./.github/workflows/scripts/build-example.sh android
- name: Start Firestore Emulator
run: cd ./.github/workflows/scripts && ./start-firestore-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
uses: reactivecircus/android-emulator-runner@v2
with:
Expand Down Expand Up @@ -61,8 +61,8 @@ jobs:
flutter config --enable-macos-desktop
- name: "Build iOS Example"
run: ./.github/workflows/scripts/build-example.sh ios
- name: Start Firestore Emulator
run: cd ./.github/workflows/scripts && ./start-firestore-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive iOS Example"
run: ./.github/workflows/scripts/drive-example.sh ios
- name: "Build MacOS Example"
Expand All @@ -73,7 +73,7 @@ jobs:
run: ./.github/workflows/scripts/drive-example.sh macos

web:
# Using macos instead of ubuntu as Web app can't connect to Firebase Firestore emulator
# Using macos instead of ubuntu as Web app can't connect to Firebase emulator
# when running on ubuntu.
runs-on: macos-latest
timeout-minutes: 15
Expand All @@ -88,7 +88,7 @@ jobs:
./.github/workflows/scripts/install-tools.sh
sudo npm i -g firebase-tools
flutter config --enable-web
- name: Start Firestore Emulator
run: cd ./.github/workflows/scripts && ./start-firestore-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
run: ./.github/workflows/scripts/drive-example.sh web
14 changes: 7 additions & 7 deletions .github/workflows/firebase_functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ jobs:
sudo npm i -g firebase-tools
- name: "Build Example"
run: ./.github/workflows/scripts/build-example.sh android
- name: Start Functions Emulator
run: cd ./.github/workflows/scripts && ./start-functions-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
uses: reactivecircus/android-emulator-runner@v2
with:
Expand Down Expand Up @@ -60,8 +60,8 @@ jobs:
sudo npm i -g firebase-tools
- name: "Build iOS Example"
run: ./.github/workflows/scripts/build-example.sh ios
- name: Start Functions Emulator
run: cd ./.github/workflows/scripts && ./start-functions-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive iOS Example"
run: ./.github/workflows/scripts/drive-example.sh ios
- name: "Build MacOS Example"
Expand All @@ -70,7 +70,7 @@ jobs:
run: ./.github/workflows/scripts/drive-example.sh macos

web:
# Using macos instead of ubuntu as Web app can't connect to Firebase Functions emulator
# Using macos instead of ubuntu as Web app can't connect to Firebase emulator
# when running on ubuntu.
runs-on: macos-latest
timeout-minutes: 15
Expand All @@ -85,7 +85,7 @@ jobs:
./.github/workflows/scripts/install-tools.sh
flutter config --enable-web
sudo npm i -g firebase-tools
- name: Start Functions Emulator
run: cd ./.github/workflows/scripts && ./start-functions-emulator.sh
- name: Start Firebase Emulator
run: cd ./.github/workflows/scripts && ./start-firebase-emulator.sh
- name: "Drive Example"
run: ./.github/workflows/scripts/drive-example.sh web
6 changes: 5 additions & 1 deletion .github/workflows/scripts/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
"firestore": {
"port": "8080"
},
"auth": {
"port": "9099"
},
"ui": {
"enabled": false
"enabled": true,
russellwheatley marked this conversation as resolved.
Show resolved Hide resolved
"port": 4000
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ if [[ ! -d "functions/node_modules" ]]; then
cd functions && npm i && cd ..
fi

EMU_START_COMMAND="firebase emulators:start --only auth,firestore,functions --project react-native-firebase-testing"

IS_CI="${CI}${CONTINUOUS_INTEGRATION}${BUILD_NUMBER}${RUN_ID}"
if [[ -n "${IS_CI}" ]]; then
firebase emulators:start --only functions &
until curl --output /dev/null --head --silent http://localhost:5001; do
echo "Waiting for Functions emulator to come online..."
$EMU_START_COMMAND &
until curl --output /dev/null --silent --fail http://localhost:8080; do
russellwheatley marked this conversation as resolved.
Show resolved Hide resolved
echo "Waiting for Firebase emulator to come online..."
sleep 2
done
echo "Functions emulator is online!"
echo "Firebase emulator is online!"
else
firebase emulators:start --only functions
$EMU_START_COMMAND
fi
17 changes: 0 additions & 17 deletions .github/workflows/scripts/start-firestore-emulator.sh

This file was deleted.

2 changes: 1 addition & 1 deletion packages/firebase_auth/firebase_auth/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 0.21.0-nullsafety.0

Migrated to null safety (#4633)
- **FEAT**: Migrated to null safety (#4633)

## 0.20.0+1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,6 @@ public class Constants {
public static final String HANDLE_CODE_IN_APP = "handleCodeInApp";
public static final String ACTION_CODE_SETTINGS = "actionCodeSettings";
public static final String AUTO_RETRIEVED_SMS_CODE_FOR_TESTING = "autoRetrievedSmsCodeForTesting";
public static final String HOST = "host";
public static final String PORT = "port";
}
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,18 @@ private Task<Void> signOut(Map<String, Object> arguments) {
});
}

private Task<Void> useEmulator(Map<String, Object> arguments) {
return Tasks.call(
cachedThreadPool,
() -> {
FirebaseAuth firebaseAuth = getAuth(arguments);
String host = (String) arguments.get(Constants.HOST);
int port = (int) arguments.get(Constants.PORT);
firebaseAuth.useEmulator(host, port);
return null;
});
}

private Task<Map<String, Object>> verifyPasswordResetCode(Map<String, Object> arguments) {
return Tasks.call(
cachedThreadPool,
Expand Down Expand Up @@ -1196,6 +1208,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
case "Auth#signOut":
methodCallTask = signOut(call.arguments());
break;
case "Auth#useEmulator":
methodCallTask = useEmulator(call.arguments());
break;
case "Auth#verifyPasswordResetCode":
methodCallTask = verifyPasswordResetCode(call.arguments());
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:usesCleartextTraffic="true"
android:name="io.flutter.app.FlutterApplication"
android:label="firebaseauthexample"
android:icon="@mipmap/ic_launcher">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand Down
3 changes: 3 additions & 0 deletions packages/firebase_auth/firebase_auth/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

// @dart=2.9

//import 'package:firebase_auth/firebase_auth.dart'; // Only needed if you configure the Auth Emulator below
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_signin_button/button_builder.dart';
Expand All @@ -14,6 +15,8 @@ import './signin_page.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Uncomment this to use the auth emulator for testing
// await FirebaseAuth.instance.useEmulator('http://localhost:9099');
runApp(AuthExampleApp());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// @dart=2.9

import 'package:drive/drive.dart' as drive;
//import 'package:firebase_auth/firebase_auth.dart'; // only needed if you use the Auth Emulator
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_test/flutter_test.dart';

Expand All @@ -19,6 +20,13 @@ bool USE_EMULATOR = false;
void testsMain() {
setUpAll(() async {
await Firebase.initializeApp();

// Configure the Auth test suite to use the Auth Emulator
// This may not be enabled until the test suite is ported to:
// - have ability to create disabled users
// - have ability to fetch OOB and SMS verification codes
// JS implementation to port to dart here: https://github.com/invertase/react-native-firebase/pull/4552/commits/4c688413cb6516ecfdbd4ea325103d0d8d8d84a8#diff-44ccd5fb03b0d9e447820032866f2494c5a400a52873f0f65518d06aedafe302
// await FirebaseAuth.instance.useEmulator('http://localhost:9099');
});

runInstanceTests();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)flutter
[self signInWithEmailLink:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Auth#signOut" isEqualToString:call.method]) {
[self signOut:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Auth#useEmulator" isEqualToString:call.method]) {
[self useEmulator:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Auth#verifyPasswordResetCode" isEqualToString:call.method]) {
[self verifyPasswordResetCode:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Auth#verifyPhoneNumber" isEqualToString:call.method]) {
Expand Down Expand Up @@ -552,6 +554,12 @@ - (void)signOut:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult
}
}

- (void)useEmulator:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
FIRAuth *auth = [self getFIRAuthFromArguments:arguments];
[auth useEmulatorWithHost:arguments[@"host"] port:[arguments[@"port"] integerValue]];
result.success(nil);
}

- (void)verifyPasswordResetCode:(id)arguments
withMethodCallResult:(FLTFirebaseMethodCallResult *)result {
FIRAuth *auth = [self getFIRAuthFromArguments:arguments];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'dart:async';
import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

Expand Down
33 changes: 33 additions & 0 deletions packages/firebase_auth/firebase_auth/lib/src/firebase_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,39 @@ class FirebaseAuth extends FirebasePluginPlatform {
return null;
}

/// Changes this instance to point to an Auth emulator running locally.
///
/// Set the [origin] of the local emulator, such as "http://localhost:9099"
///
/// Note: Must be called immediately, prior to accessing auth methods.
/// Do not use with production credentials as emulator traffic is not encrypted.
Future<void> useEmulator(String origin) async {
assert(origin.isNotEmpty);
String mappedOrigin = origin;

// Android considers localhost as 10.0.2.2 - automatically handle this for users.
if (defaultTargetPlatform == TargetPlatform.android) {
Salakar marked this conversation as resolved.
Show resolved Hide resolved
if (mappedOrigin.startsWith('http://localhost')) {
Salakar marked this conversation as resolved.
Show resolved Hide resolved
mappedOrigin =
mappedOrigin.replaceFirst('http://localhost', 'http://10.0.2.2');
} else if (mappedOrigin.startsWith('http://127.0.0.1')) {
mappedOrigin =
mappedOrigin.replaceFirst('http://127.0.0.1', 'http://10.0.2.2');
}
}

// Native calls take the host and port split out
final hostPortRegex = RegExp(r'^http:\/\/([\w\d.]+):(\d+)$');
final RegExpMatch? match = hostPortRegex.firstMatch(mappedOrigin);
if (match == null) {
throw ArgumentError('firebase.auth().useEmulator() origin format error');
}
// Two non-empty groups in RegExp match - which is null-tested - these are non-null now
final String host = match.group(1)!;
final int port = int.parse(match.group(2)!);
await _delegate.useEmulator(host, port);
}

/// Applies a verification code sent to the user by email or other out-of-band
/// mechanism.
///
Expand Down
Loading