Skip to content

Commit

Permalink
feat(web): automatically inject Firebase JS SDKs (#7359)
Browse files Browse the repository at this point in the history
Co-authored-by: Mike Diarmid <mike.diarmid@gmail.com>
  • Loading branch information
Ehesp and Salakar committed Dec 2, 2021
1 parent 8c487fb commit 5f4c414
Show file tree
Hide file tree
Showing 24 changed files with 125 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:cloud_firestore_web/src/internals.dart';
import 'package:cloud_firestore_web/src/load_bundle_task_web.dart';
import 'package:cloud_firestore_web/src/utils/web_utils.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:firebase_core_web/firebase_core_web_interop.dart'
as core_interop;
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
Expand All @@ -36,6 +37,7 @@ class FirebaseFirestoreWeb extends FirebaseFirestorePlatform {

/// Called by PluginRegistry to register this plugin for Flutter Web
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('firestore');
FirebaseFirestorePlatform.instance = FirebaseFirestoreWeb();
}

Expand Down
21 changes: 1 addition & 20 deletions packages/cloud_functions/cloud_functions/example/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,7 @@
</head>

<body>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-functions.js"></script>

<!-- Initialize Firebase -->
<!-- <script>
const firebaseConfig = {
apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",
authDomain: "react-native-firebase-testing.firebaseapp.com",
databaseURL: "https://react-native-firebase-testing.firebaseio.com",
projectId: "react-native-firebase-testing",
storageBucket: "react-native-firebase-testing.appspot.com",
messagingSenderId: "448618578101",
appId: "1:448618578101:web:0b650370bb29e29cac3efc",
measurementId: "G-F79DJ0VFGS"
};
// Initialize Firebase
let firebaseApp = firebase.initializeApp(firebaseConfig);
</script> -->
<script src="main.dart.js" type="application/javascript"></script>
</body>

</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import 'package:cloud_functions_platform_interface/cloud_functions_platform_interface.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:firebase_core_web/firebase_core_web_interop.dart'
as core_interop;
Expand Down Expand Up @@ -34,6 +35,7 @@ class FirebaseFunctionsWeb extends FirebaseFunctionsPlatform {

/// Create the default instance of the [FirebaseFunctionsPlatform] as a [FirebaseFunctionsWeb]
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('functions');
FirebaseFunctionsPlatform.instance = FirebaseFunctionsWeb.instance;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@

import 'dart:async';

import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:firebase_analytics/firebase_analytics.dart';

import 'tabs_page.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0',
appId: '1:448618578101:ios:2bc5c1fe2ec336f8ac3efc',
messagingSenderId: '448618578101',
apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',
authDomain: 'react-native-firebase-testing.firebaseapp.com',
databaseURL: 'https://react-native-firebase-testing.firebaseio.com',
projectId: 'react-native-firebase-testing',
storageBucket: 'react-native-firebase-testing.appspot.com',
messagingSenderId: '448618578101',
appId: '1:448618578101:web:772d484dc9eb15e9ac3efc',
measurementId: 'G-0N1G9FLDZE',
),
);
runApp(const MyApp());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,6 @@

<title>example</title>
<link rel="manifest" href="manifest.json">

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-analytics.js"></script>

<!-- <script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",
authDomain: "react-native-firebase-testing.firebaseapp.com",
databaseURL: "https://react-native-firebase-testing.firebaseio.com",
projectId: "react-native-firebase-testing",
storageBucket: "react-native-firebase-testing.appspot.com",
messagingSenderId: "448618578101",
appId: "1:448618578101:web:772d484dc9eb15e9ac3efc",
measurementId: "G-0N1G9FLDZE"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
firebase.analytics();
</script> -->


</head>

<body>
Expand All @@ -59,4 +33,4 @@
<script src="main.dart.js" type="application/javascript"></script>
</body>

</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'package:firebase_analytics_platform_interface/firebase_analytics_platform_interface.dart';
import 'package:firebase_analytics_web/utils/exception.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:firebase_core_web/firebase_core_web_interop.dart'
as core_interop;
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
Expand All @@ -28,6 +29,7 @@ class FirebaseAnalyticsWeb extends FirebaseAnalyticsPlatform {

/// Called by PluginRegistry to register this plugin for Flutter Web
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('analytics');
FirebaseAnalyticsPlatform.instance = FirebaseAnalyticsWeb();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0',
appId: '1:448618578101:ios:2bc5c1fe2ec336f8ac3efc',
messagingSenderId: '448618578101',
projectId: 'react-native-firebase-testing',
));
options: const FirebaseOptions(
apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',
authDomain: 'react-native-firebase-testing.firebaseapp.com',
databaseURL: 'https://react-native-firebase-testing.firebaseio.com',
projectId: 'react-native-firebase-testing',
storageBucket: 'react-native-firebase-testing.appspot.com',
messagingSenderId: '448618578101',
appId: '1:448618578101:web:772d484dc9eb15e9ac3efc',
measurementId: 'G-0N1G9FLDZE'),
);

// Activate app check after initialization, but before
// usage of any Firebase services.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,6 @@
<title>example</title>
</head>
<body>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app-check.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",
authDomain: "react-native-firebase-testing.firebaseapp.com",
databaseURL: "https://react-native-firebase-testing.firebaseio.com",
projectId: "react-native-firebase-testing",
storageBucket: "react-native-firebase-testing.appspot.com",
messagingSenderId: "448618578101",
appId: "1:448618578101:web:772d484dc9eb15e9ac3efc",
measurementId: "G-0N1G9FLDZE"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<script src="main.dart.js" type="application/javascript"></script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import 'package:firebase_app_check_platform_interface/firebase_app_check_platform_interface.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

import 'src/internals.dart';
Expand All @@ -22,6 +23,7 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {

/// Called by PluginRegistry to register this plugin for Flutter Web
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('app-check');
FirebaseAppCheckPlatform.instance = FirebaseAppCheckWeb.instance;
}

Expand Down
19 changes: 1 addition & 18 deletions packages/firebase_auth/firebase_auth/example/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,7 @@
</head>

<body>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-auth.js"></script>
<!-- <script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0",
authDomain: "react-native-firebase-testing.firebaseapp.com",
databaseURL: "https://react-native-firebase-testing.firebaseio.com",
projectId: "react-native-firebase-testing",
storageBucket: "react-native-firebase-testing.appspot.com",
messagingSenderId: "448618578101",
appId: "1:448618578101:web:0b650370bb29e29cac3efc",
measurementId: "G-F79DJ0VFGS"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script> -->
<script src="main.dart.js" type="application/javascript"></script>
</body>

</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import 'dart:async';

import 'package:firebase_auth_platform_interface/firebase_auth_platform_interface.dart';
import 'package:firebase_auth_web/src/utils/web_utils.dart';
import 'src/interop/auth.dart' as auth_interop;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core_web/firebase_core_web.dart';
import 'package:firebase_core_web/firebase_core_web_interop.dart'
as core_interop;
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

import 'src/firebase_auth_web_user.dart';
import 'src/firebase_auth_web_confirmation_result.dart';
import 'src/firebase_auth_web_recaptcha_verifier_factory.dart';
import 'src/firebase_auth_web_user.dart';
import 'src/firebase_auth_web_user_credential.dart';
import 'src/firebase_auth_web_confirmation_result.dart';
import 'src/interop/auth.dart' as auth_interop;

/// The web delegate implementation for [FirebaseAuth].
class FirebaseAuthWeb extends FirebaseAuthPlatform {
Expand Down Expand Up @@ -69,6 +70,7 @@ class FirebaseAuthWeb extends FirebaseAuthPlatform {

/// Called by PluginRegistry to register this plugin for Flutter Web
static void registerWith(Registrar registrar) {
FirebaseCoreWeb.registerService('auth');
FirebaseAuthPlatform.instance = FirebaseAuthWeb.instance;
RecaptchaVerifierFactoryPlatform.instance =
RecaptchaVerifierFactoryWeb.instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,51 @@ class FirebaseCoreWeb extends FirebasePlatform {
FirebasePlatform.instance = FirebaseCoreWeb();
}

/// Returns whether `requirejs` is within the global context (usually the
/// case in development).
bool get _isRequireJsDefined {
return context['require'] != null;
}

/// Returns the Firebase JS SDK Version to use.
///
/// You can override the supported version by attaching a version string to
/// the window (window.flutterfire_web_sdk_version = 'x.x.x'). Do so at your
/// own risk as the version might be unsupported or untested against.
String get _firebaseSDKVersion {
return context['flutterfire_web_sdk_version'] ??
supportedFirebaseJsSdkVersion;
}

/// Returns a list of services which won't be automatically injected on
/// initilization. This is useful incases where you wish to manually include
/// the scripts (e.g. in countries where you must request the users permission
/// to include Analytics).
///
/// You can do this by attaching an array of services to the window, e.g:
///
/// window.flutterfire_ignore_scripts = ['analytics'];
///
/// You must ensure the Firebase script is injected before using the service.
List<String> get _ignoredServiceScripts {
try {
JsObject ignored =
JsObject.fromBrowserObject(context['flutterfire_ignore_scripts']);

if (ignored is Iterable) {
return (ignored as Iterable)
.map((e) => e.toString())
.toList(growable: false);
}
} catch (e) {
// Noop
}

return [];
}

/// Injects a `script` with a `src` dynamically into the head of the current
/// document.
Future<void> _injectSrcScript(String src) async {
ScriptElement script = ScriptElement();
script.type = 'text/javascript';
Expand All @@ -49,6 +85,8 @@ class FirebaseCoreWeb extends FirebasePlatform {
await script.onLoad.first;
}

/// Initializes the Firebase JS SDKs by injecting them into the `head` of the
/// document when Firebase is initalized.
Future<void> _initializeCore() async {
// If Firebase is already available, core has already been initialized
// (or the user has added the scripts to their html file).
Expand All @@ -57,6 +95,7 @@ class FirebaseCoreWeb extends FirebasePlatform {
}

String version = _firebaseSDKVersion;
List<String> ignored = _ignoredServiceScripts;

// This must be loaded first!
await _injectSrcScript(
Expand All @@ -65,6 +104,10 @@ class FirebaseCoreWeb extends FirebasePlatform {

await Future.wait(
_services.values.map((service) {
if (ignored.contains(service.name)) {
return Future.value();
}

return _injectSrcScript(
'https://www.gstatic.com/firebasejs/$version/firebase-${service.name}.js',
);
Expand All @@ -85,6 +128,7 @@ class FirebaseCoreWeb extends FirebasePlatform {
}

String version = _firebaseSDKVersion;
List<String> ignored = _ignoredServiceScripts;

// In dev, requirejs is loaded in
JsObject require = JsObject.fromBrowserObject(context['require']);
Expand Down Expand Up @@ -121,7 +165,9 @@ class FirebaseCoreWeb extends FirebasePlatform {

List<String> services = ['@firebase/app'];
_services.values.forEach((service) {
services.add('@firebase/${service.name}');
if (!ignored.contains(service.name)) {
services.add('@firebase/${service.name}');
}
});

context.callMethod('require', [
Expand Down
17 changes: 10 additions & 7 deletions packages/firebase_database/firebase_database/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final FirebaseApp app = await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0',
appId: '1:448618578101:ios:2bc5c1fe2ec336f8ac3efc',
messagingSenderId: '448618578101',
projectId: 'react-native-firebase-testing',
databaseURL: 'https://react-native-firebase-testing.firebaseio.com',
));
options: const FirebaseOptions(
apiKey: 'AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0',
authDomain: 'react-native-firebase-testing.firebaseapp.com',
databaseURL: 'https://react-native-firebase-testing.firebaseio.com',
projectId: 'react-native-firebase-testing',
storageBucket: 'react-native-firebase-testing.appspot.com',
messagingSenderId: '448618578101',
appId: '1:448618578101:web:772d484dc9eb15e9ac3efc',
measurementId: 'G-0N1G9FLDZE'),
);
runApp(MaterialApp(
title: 'Flutter Database Example',
home: MyHomePage(app: app),
Expand Down
Loading

0 comments on commit 5f4c414

Please sign in to comment.