diff --git a/packages/firebase_core/firebase_core_web/CHANGELOG.md b/packages/firebase_core/firebase_core_web/CHANGELOG.md
new file mode 100644
index 000000000000..7be26166a1f2
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/CHANGELOG.md
@@ -0,0 +1,3 @@
+# 0.1.0
+
+- Initial open-source release.
diff --git a/packages/firebase_core/firebase_core_web/LICENSE b/packages/firebase_core/firebase_core_web/LICENSE
new file mode 100644
index 000000000000..0c382ce171cc
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packages/firebase_core/firebase_core_web/README.md b/packages/firebase_core/firebase_core_web/README.md
new file mode 100644
index 000000000000..87303f0375f6
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/README.md
@@ -0,0 +1,51 @@
+# firebase_core_web
+
+The web implementation of [`firebase_core`][1].
+
+## Usage
+
+### Import the package
+
+To use this plugin in your Flutter app on the web, simply add it as a
+dependency in your `pubspec.yaml` alongside the base `firebase_core`
+plugin.
+
+_(This is only temporary: in the future we hope to make this package
+an "endorsed" implementation of `firebase_core`, so it will automatically
+be included in your app when you run your Flutter app on the web.)_
+
+Add this to your `pubspec.yaml`:
+
+```yaml
+...
+dependencies:
+ ...
+ firebase_core: ^0.4.1
+ firebase_core_web: ^0.1.0
+ ...
+```
+
+### Updating `index.html`
+
+Due to [this bug in dartdevc][2], you will need to manually add the Firebase
+JavaScript file to you `index.html` file.
+
+In your app directory, edit `web/index.html` to add the line:
+
+```html
+
+ ...
+
+
+
+
+
+```
+
+### Using the plugin
+
+Once you have added the `firebase_core_web` dependency to your pubspec,
+you can use `package:firebase_core` as normal.
+
+[1]: ../firebase_core/firebase_core
+[2]: https://github.com/dart-lang/sdk/issues/33979
diff --git a/packages/firebase_core/firebase_core_web/ios/firebase_core_web.podspec b/packages/firebase_core/firebase_core_web/ios/firebase_core_web.podspec
new file mode 100644
index 000000000000..c6e11ef16e16
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/ios/firebase_core_web.podspec
@@ -0,0 +1,21 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
+#
+Pod::Spec.new do |s|
+ s.name = 'firebase_core_web'
+ s.version = '0.1.0'
+ s.summary = 'No-op implementation of firebase_core_web web plugin to avoid build issues on iOS'
+ s.description = <<-DESC
+ temp fake google_sign_in_web plugin
+ DESC
+ s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_core/firebase_core_web'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' }
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.public_header_files = 'Classes/**/*.h'
+ s.dependency 'Flutter'
+
+ s.ios.deployment_target = '8.0'
+ end
+
diff --git a/packages/firebase_core/firebase_core_web/lib/firebase_core_web.dart b/packages/firebase_core/firebase_core_web/lib/firebase_core_web.dart
new file mode 100644
index 000000000000..75ae87075aa6
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/lib/firebase_core_web.dart
@@ -0,0 +1,86 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
+import 'package:flutter_web_plugins/flutter_web_plugins.dart';
+import 'package:js/js_util.dart' as js_util;
+
+import 'src/firebase_js.dart';
+
+/// The implementation of `firebase_core` for web.
+class FirebaseCoreWeb extends FirebaseCorePlatform {
+ /// Creates a new instance of [FirebaseCoreWeb].
+ FirebaseCoreWeb() {
+ if (firebase == null) {
+ throw StateError('firebase.js has not been loaded');
+ }
+ }
+
+ /// Registers that [FirebaseCoreWeb] is the platform implementation.
+ static void registerWith(Registrar registrar) {
+ FirebaseCorePlatform.instance = FirebaseCoreWeb();
+ }
+
+ @override
+ Future appNamed(String name) async {
+ try {
+ final App jsApp = firebase.app(name);
+ if (jsApp == null) {
+ return null;
+ }
+ return _createFromJsApp(jsApp);
+ } catch (e) {
+ if (_isFirebaseError(e)) {
+ return null;
+ }
+ rethrow;
+ }
+ }
+
+ @override
+ Future configure(String name, FirebaseOptions options) async {
+ firebase.initializeApp(_createFromFirebaseOptions(options), name);
+ }
+
+ @override
+ Future> allApps() async {
+ final List jsApps = firebase.apps;
+ return jsApps.map(_createFromJsApp).toList();
+ }
+}
+
+/// Returns `true` if [e] is a `FirebaseError`.
+bool _isFirebaseError(dynamic e) {
+ return js_util.getProperty(e, 'name') == 'FirebaseError';
+}
+
+PlatformFirebaseApp _createFromJsApp(App jsApp) {
+ return PlatformFirebaseApp(jsApp.name, _createFromJsOptions(jsApp.options));
+}
+
+FirebaseOptions _createFromJsOptions(Options options) {
+ return FirebaseOptions(
+ apiKey: options.apiKey,
+ trackingID: options.measurementId,
+ gcmSenderID: options.messagingSenderId,
+ projectID: options.projectId,
+ googleAppID: options.appId,
+ databaseURL: options.databaseURL,
+ storageBucket: options.storageBucket,
+ );
+}
+
+Options _createFromFirebaseOptions(FirebaseOptions options) {
+ return Options(
+ apiKey: options.apiKey,
+ measurementId: options.trackingID,
+ messagingSenderId: options.gcmSenderID,
+ projectId: options.projectID,
+ appId: options.googleAppID,
+ databaseURL: options.databaseURL,
+ storageBucket: options.storageBucket,
+ );
+}
diff --git a/packages/firebase_core/firebase_core_web/lib/src/firebase_js.dart b/packages/firebase_core/firebase_core_web/lib/src/firebase_js.dart
new file mode 100644
index 000000000000..d7323c874b27
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/lib/src/firebase_js.dart
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+@JS()
+library firebase_js;
+
+import 'package:js/js.dart';
+
+/// A Firebase app.
+@JS()
+class App {
+ /// The name of the app.
+ external String get name;
+
+ /// The options that the app was configured with.
+ external Options get options;
+}
+
+/// Options for configuring an app.
+@JS()
+@anonymous
+class Options {
+ /// Creates an options JavaScript object.
+ external factory Options({
+ String apiKey,
+ String authDomain,
+ String databaseURL,
+ String projectId,
+ String storageBucket,
+ String messagingSenderId,
+ String appId,
+ String measurementId,
+ });
+
+ /// The API key used to authenticate requests.
+ external String get apiKey;
+
+ /// Domain for authentication.
+ external String get authDomain;
+
+ /// Realtime Database URL.
+ external String get databaseURL;
+
+ /// The Google Cloud project ID.
+ external String get projectId;
+
+ /// The Google Cloud Storage bucket name.
+ external String get storageBucket;
+
+ /// The project number used to configure Messaging.
+ external String get messagingSenderId;
+
+ /// The Google App ID that uniquely identifies an app instance.
+ external String get appId;
+
+ /// An ID used for analytics.
+ external String get measurementId;
+}
+
+/// The `firebase` namespace.
+@JS()
+class FirebaseCore {
+ /// Returns a list of initialized apps.
+ external List get apps;
+
+ /// Initializes the app named [name] with the given [options].
+ external App initializeApp(Options options, String name);
+
+ /// Returns the already-initialized app with the given [name].
+ external App app(String name);
+}
+
+/// Return the `firebase` object.
+@JS()
+external FirebaseCore get firebase;
diff --git a/packages/firebase_core/firebase_core_web/pubspec.yaml b/packages/firebase_core/firebase_core_web/pubspec.yaml
new file mode 100644
index 000000000000..ca39fd5d1b8f
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/pubspec.yaml
@@ -0,0 +1,30 @@
+name: firebase_core_web
+description: The web implementation of firebase_core
+author: Flutter Team
+homepage: https://github.com/FirebaseExtended/flutterfire/packages/firebase_core/firebase_core_web
+version: 0.1.0
+
+flutter:
+ plugin:
+ platforms:
+ web:
+ pluginClass: FirebaseCoreWeb
+ fileName: firebase_core_web.dart
+
+dependencies:
+ firebase_core_platform_interface: ^1.0.0
+ flutter:
+ sdk: flutter
+ flutter_web_plugins:
+ sdk: flutter
+ meta: ^1.1.7
+ js: ^0.6.1
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ firebase_core: ^0.4.2+1
+
+environment:
+ sdk: ">=2.0.0-dev.28.0 <3.0.0"
+ flutter: ">=1.9.1+hotfix.2 <2.0.0"
diff --git a/packages/firebase_core/firebase_core_web/test/firebase_core_web_test.dart b/packages/firebase_core/firebase_core_web/test/firebase_core_web_test.dart
new file mode 100644
index 000000000000..f2bd164a07b4
--- /dev/null
+++ b/packages/firebase_core/firebase_core_web/test/firebase_core_web_test.dart
@@ -0,0 +1,72 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+@TestOn('browser')
+
+import 'dart:js' as js;
+
+import 'package:flutter_test/flutter_test.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_core_web/firebase_core_web.dart';
+import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
+
+void main() {
+ group('$FirebaseCoreWeb', () {
+ setUp(() async {
+ final js.JsObject firebaseMock = js.JsObject.jsify({});
+ js.context['firebase'] = firebaseMock;
+ FirebaseCorePlatform.instance = FirebaseCoreWeb();
+ });
+
+ test('FirebaseApp.allApps() calls firebase.apps', () async {
+ js.context['firebase']['apps'] = js.JsArray();
+ final List apps = await FirebaseApp.allApps();
+ expect(apps, hasLength(0));
+ });
+
+ test('FirebaseApp.appNamed() calls firebase.app', () async {
+ js.context['firebase']['app'] = js.allowInterop((String name) {
+ return js.JsObject.jsify({
+ 'name': name,
+ 'options': {'appId': '123'},
+ });
+ });
+ final FirebaseApp app = await FirebaseApp.appNamed('foo');
+ expect(app.name, equals('foo'));
+
+ final FirebaseOptions options = await app.options;
+ expect(options.googleAppID, equals('123'));
+ });
+
+ test('FirebaseApp.configure() calls firebase.initializeApp', () async {
+ bool appConfigured = false;
+
+ js.context['firebase']['app'] = js.allowInterop((String name) {
+ if (appConfigured) {
+ return js.JsObject.jsify({
+ 'name': name,
+ 'options': {'appId': '123'},
+ });
+ } else {
+ return null;
+ }
+ });
+ js.context['firebase']['initializeApp'] =
+ js.allowInterop((js.JsObject options, String name) {
+ appConfigured = true;
+ return js.JsObject.jsify({
+ 'name': name,
+ 'options': options,
+ });
+ });
+ final FirebaseApp app = await FirebaseApp.configure(
+ name: 'foo',
+ options: const FirebaseOptions(googleAppID: '123'),
+ );
+ expect(app.name, equals('foo'));
+
+ final FirebaseOptions options = await app.options;
+ expect(options.googleAppID, equals('123'));
+ });
+ });
+}