From 647c213a4ecb9ff0f3d90e4d774a26d3c590e9ce Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 14 Dec 2019 22:28:07 +0000 Subject: [PATCH 001/144] - Created cloud_firestore_platform interface package - Migrated DocumentReference and CollectionReference to use interfaces --- .../.gitignore | 75 ++++ .../.metadata | 10 + .../CHANGELOG.md | 3 + .../LICENSE | 1 + .../README.md | 14 + .../analysis_options.yaml | 12 + .../cloud_firestore_platform_interface.dart | 168 ++++++++ .../lib/src/blob.dart | 15 + .../lib/src/collection_reference.dart | 46 +++ .../lib/src/document_change.dart | 59 +++ .../lib/src/document_reference.dart | 98 +++++ .../lib/src/document_reference_interface.dart | 81 ++++ .../lib/src/document_snapshot.dart | 45 +++ .../lib/src/field_path.dart | 21 + .../lib/src/field_value.dart | 68 ++++ .../lib/src/firestore_message_codec.dart | 124 ++++++ .../lib/src/geo_point.dart | 19 + .../method_channel_collection_reference.dart | 46 +++ .../lib/src/method_channel_firestore.dart | 134 ++++++ .../lib/src/query.dart | 71 ++++ .../lib/src/query_interface.dart | 381 ++++++++++++++++++ .../lib/src/query_snapshot.dart | 42 ++ .../lib/src/snapshot_metadata.dart | 28 ++ .../lib/src/source.dart | 37 ++ .../lib/src/timestamp.dart | 98 +++++ .../lib/src/transaction.dart | 65 +++ .../src/transaction_platform_interface.dart | 77 ++++ .../lib/src/utils/auto_id_generator.dart | 34 ++ .../lib/src/write_batch.dart | 101 +++++ .../src/write_batch_platform_interface.dart | 50 +++ .../pubspec.yaml | 21 + 31 files changed, 2044 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/.metadata create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/README.md create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore b/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore new file mode 100644 index 000000000000..bb431f0d5b47 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore @@ -0,0 +1,75 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata b/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata new file mode 100644 index 000000000000..bae65c434b98 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 18cd7a3601bcffb36fdf2f679f763b5e827c2e8e + channel: beta + +project_type: package diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..ac071598e5d4 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - TODO: Add release date. + +* TODO: Describe initial release. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE b/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE new file mode 100644 index 000000000000..ba75c69f7f21 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/README.md b/packages/cloud_firestore/cloud_firestore_platform_interface/README.md new file mode 100644 index 000000000000..9e6d2ecdba2f --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/README.md @@ -0,0 +1,14 @@ +# cloud_firestore_platfrom_interface + +A new Flutter package project. + +## Getting Started + +This project is a starting point for a Dart +[package](https://flutter.dev/developing-packages/), +a library module containing code that can be shared easily across +multiple Flutter or Dart projects. + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml new file mode 100644 index 000000000000..bbfa25e2146a --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml @@ -0,0 +1,12 @@ +# This is a temporary file to allow us to land a new set of linter rules in a +# series of manageable patches instead of one gigantic PR. It disables some of +# the new lints that are already failing on this plugin, for this plugin. It +# should be deleted and the failing lints addressed as soon as possible. + +include: ../../../analysis_options.yaml + +analyzer: + errors: + curly_braces_in_flow_control_structures: ignore + public_member_api_docs: ignore + unawaited_futures: ignore diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart new file mode 100644 index 000000000000..b9757441008c --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -0,0 +1,168 @@ +library cloud_firestore_platform_interface; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; +import 'dart:ui'; +import 'dart:math'; + +import 'package:collection/collection.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show required, visibleForTesting; + +part 'src/method_channel_firestore.dart'; + +part 'src/blob.dart'; + +part 'src/utils/auto_id_generator.dart'; + +part 'src/collection_reference.dart'; +part 'src/method_channel_collection_reference.dart'; + +part 'src/document_change.dart'; + +part 'src/document_reference.dart'; + +part 'src/document_reference_interface.dart'; + +part 'src/document_snapshot.dart'; + +part 'src/field_path.dart'; + +part 'src/field_value.dart'; + +part 'src/firestore_message_codec.dart'; + +part 'src/geo_point.dart'; + +part 'src/query.dart'; + +part 'src/query_interface.dart'; + +part 'src/query_snapshot.dart'; + +part 'src/snapshot_metadata.dart'; + +part 'src/source.dart'; + +part 'src/timestamp.dart'; + +part 'src/transaction.dart'; + +part 'src/transaction_platform_interface.dart'; + +part 'src/write_batch.dart'; + +part 'src/write_batch_platform_interface.dart'; + +abstract class FirestorePlatform { + + FirestorePlatform(); + /// Only mock implementations should set this to `true`. + /// + /// Mockito mocks implement this class with `implements` which is forbidden + /// (see class docs). This property provides a backdoor for mocks to skip the + /// verification that the class isn't implemented with `implements`. + @visibleForTesting + bool get isMock => false; + + static FirestorePlatform get instance => _instance; + + static FirestorePlatform _instance = MethodChannelFirestore(); + + factory FirestorePlatform._withApp(PlatformFirebaseApp app) => + MethodChannelFirestore(); + + // TODO(amirh): Extract common platform interface logic. + // https://github.com/flutter/flutter/issues/43368 + static set instance(FirestorePlatform instance) { + if (!instance.isMock) { + try { + instance._verifyProvidesDefaultImplementations(); + } on NoSuchMethodError catch (_) { + throw AssertionError( + 'Platform interfaces must not be implemented with `implements`'); + } + } + _instance = instance; + } + + String appName() { + throw UnimplementedError("appName() not implemented"); + } + + /// This method ensures that [FirebaseAuthPlatform] isn't implemented with `implements`. + /// + /// See class docs for more details on why using `implements` to implement + /// [FirebaseAuthPlatform] is forbidden. + /// + /// This private method is called by the [instance] setter, which should fail + /// if the provided instance is a class implemented with `implements`. + void _verifyProvidesDefaultImplementations() {} + + /// Gets a [CollectionReference] for the specified Firestore path. + CollectionReference collection(String path) { + throw UnimplementedError('collection() is not implemented'); + } + + /// Gets a [Query] for the specified collection group. + Query collectionGroup(String path) { + throw UnimplementedError('collectionGroup() is not implemented'); + } + + /// Gets a [DocumentReference] for the specified Firestore path. + DocumentReference document(String path) { + throw UnimplementedError('document() is not implemented'); + } + + /// Creates a write batch, used for performing multiple writes as a single + /// atomic operation. + /// + /// Unlike transactions, write batches are persisted offline and therefore are + /// preferable when you don’t need to condition your writes on read data. + WriteBatch batch() { + throw UnimplementedError('batch() is not implemented'); + } + + /// Executes the given TransactionHandler and then attempts to commit the + /// changes applied within an atomic transaction. + /// + /// In the TransactionHandler, a set of reads and writes can be performed + /// atomically using the Transaction object passed to the TransactionHandler. + /// After the TransactionHandler is run, Firestore will attempt to apply the + /// changes to the server. If any of the data read has been modified outside + /// of this transaction since being read, then the transaction will be + /// retried by executing the updateBlock again. If the transaction still + /// fails after 5 retries, then the transaction will fail. + /// + /// The TransactionHandler may be executed multiple times, it should be able + /// to handle multiple executions. + /// + /// Data accessed with the transaction will not reflect local changes that + /// have not been committed. For this reason, it is required that all + /// reads are performed before any writes. Transactions must be performed + /// while online. Otherwise, reads will fail, and the final commit will fail. + /// + /// By default transactions are limited to 5 seconds of execution time. This + /// timeout can be adjusted by setting the timeout parameter. + Future> runTransaction( + TransactionHandler transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) async { + throw UnimplementedError('runTransaction() is not implemented'); + } + + @deprecated + Future enablePersistence(bool enable) async { + throw UnimplementedError('enablePersistence() is not implemented'); + } + + Future settings({bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) async { + throw UnimplementedError('settings() is not implemented'); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart new file mode 100644 index 000000000000..2e52eca55611 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -0,0 +1,15 @@ +part of cloud_firestore_platform_interface; + +class Blob { + const Blob(this.bytes); + + final Uint8List bytes; + + @override + bool operator ==(dynamic other) => + other is Blob && + const DeepCollectionEquality().equals(other.bytes, bytes); + + @override + int get hashCode => hashList(bytes); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart new file mode 100644 index 000000000000..c576d1646146 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart @@ -0,0 +1,46 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A CollectionReference object can be used for adding documents, getting +/// document references, and querying for documents (using the methods +/// inherited from [Query]). +class CollectionReference extends Query { + CollectionReference(FirestorePlatform firestore, List pathComponents) + : super(firestore: firestore, pathComponents: pathComponents); + + /// ID of the referenced collection. + String get id => _pathComponents.isEmpty ? null : _pathComponents.last; + + /// For subcollections, parent returns the containing [DocumentReference]. + /// + /// For root collections, null is returned. + DocumentReference parent() { + throw UnimplementedError("parent() is not implemented"); + } + + /// A string containing the slash-separated path to this CollectionReference + /// (relative to the root of the database). + String get path => _path; + + /// Returns a `DocumentReference` with the provided path. + /// + /// If no [path] is provided, an auto-generated ID is used. + /// + /// The unique key generated is prefixed with a client-generated timestamp + /// so that the resulting list will be chronologically-sorted. + DocumentReference document([String path]) { + throw UnimplementedError("document() is not implemented"); + } + + /// Returns a `DocumentReference` with an auto-generated ID, after + /// populating it with provided [data]. + /// + /// The unique key generated is prefixed with a client-generated timestamp + /// so that the resulting list will be chronologically-sorted. + Future add(Map data) async { + throw UnimplementedError("add() is not implemented"); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart new file mode 100644 index 000000000000..253e10c0d525 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart @@ -0,0 +1,59 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// An enumeration of document change types. +enum DocumentChangeType { + /// Indicates a new document was added to the set of documents matching the + /// query. + added, + + /// Indicates a document within the query was modified. + modified, + + /// Indicates a document within the query was removed (either deleted or no + /// longer matches the query. + removed, +} + +/// A DocumentChange represents a change to the documents matching a query. +/// +/// It contains the document affected and the type of change that occurred +/// (added, modified, or removed). +class DocumentChange { + DocumentChange._(Map data, FirestorePlatform firestore) + : oldIndex = data['oldIndex'], + newIndex = data['newIndex'], + document = DocumentSnapshot( + data['path'], + _asStringKeyedMap(data['document']), + SnapshotMetadata(data["metadata"]["hasPendingWrites"], + data["metadata"]["isFromCache"]), + firestore, + ), + type = DocumentChangeType.values.firstWhere((DocumentChangeType type) { + return type.toString() == data['type']; + }); + + /// The type of change that occurred (added, modified, or removed). + final DocumentChangeType type; + + /// The index of the changed document in the result set immediately prior to + /// this [DocumentChange] (i.e. supposing that all prior DocumentChange objects + /// have been applied). + /// + /// -1 for [DocumentChangeType.added] events. + final int oldIndex; + + /// The index of the changed document in the result set immediately after this + /// DocumentChange (i.e. supposing that all prior [DocumentChange] objects + /// and the current [DocumentChange] object have been applied). + /// + /// -1 for [DocumentChangeType.removed] events. + final int newIndex; + + /// The document affected by this change. + final DocumentSnapshot document; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart new file mode 100644 index 000000000000..4949191ba67b --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart @@ -0,0 +1,98 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +class MethodChannelDocumentReference extends DocumentReference { + MethodChannelDocumentReference(FirestorePlatform firestore, List pathComponents) + :assert(firestore != null), super(firestore, pathComponents); + + @override + Future setData(Map data, {bool merge = false}) { + return MethodChannelFirestore.channel.invokeMethod( + 'DocumentReference#setData', + { + 'app': firestore.appName(), + 'path': path, + 'data': data, + 'options': {'merge': merge}, + }, + ); + } + + @override + Future updateData(Map data) { + return MethodChannelFirestore.channel.invokeMethod( + 'DocumentReference#updateData', + { + 'app': firestore.appName(), + 'path': path, + 'data': data, + }, + ); + } + + @override + Future get({Source source = Source.serverAndCache}) async { + final Map data = + await MethodChannelFirestore.channel.invokeMapMethod( + 'DocumentReference#get', + { + 'app': firestore.appName(), + 'path': path, + 'source': _getSourceString(source), + }, + ); + return DocumentSnapshot( + data['path'], + _asStringKeyedMap(data['data']), + SnapshotMetadata(data['metadata']['hasPendingWrites'], + data['metadata']['isFromCache']), + firestore, + ); + } + + @override + Future delete() { + return MethodChannelFirestore.channel.invokeMethod( + 'DocumentReference#delete', + {'app': firestore.appName(), 'path': path}, + ); + } + + // TODO(jackson): Reduce code duplication with [Query] + @override + Stream snapshots({bool includeMetadataChanges = false}) { + assert(includeMetadataChanges != null); + Future _handle; + // It's fine to let the StreamController be garbage collected once all the + // subscribers have cancelled; this analyzer warning is safe to ignore. + StreamController controller; // ignore: close_sinks + controller = StreamController.broadcast( + onListen: () { + _handle = MethodChannelFirestore.channel.invokeMethod( + 'DocumentReference#addSnapshotListener', + { + 'app': firestore.appName(), + 'path': path, + 'includeMetadataChanges': includeMetadataChanges, + }, + ).then((dynamic result) => result); + _handle.then((int handle) { + MethodChannelFirestore._documentObservers[handle] = controller; + }); + }, + onCancel: () { + _handle.then((int handle) async { + await MethodChannelFirestore.channel.invokeMethod( + 'removeListener', + {'handle': handle}, + ); + MethodChannelFirestore._documentObservers.remove(handle); + }); + }, + ); + return controller.stream; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart new file mode 100644 index 000000000000..1c6a9f85cf33 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart @@ -0,0 +1,81 @@ +part of cloud_firestore_platform_interface; + +/// A [DocumentReference] refers to a document location in a Firestore database +/// and can be used to write, read, or listen to the location. +/// +/// The document at the referenced location may or may not exist. +/// A [DocumentReference] can also be used to create a [CollectionReference] +/// to a subcollection. +class DocumentReference { + DocumentReference(this.firestore, this._pathComponents); + + /// The Firestore instance associated with this document reference + final FirestorePlatform firestore; + final List _pathComponents; + + @override + bool operator ==(dynamic o) => + o is DocumentReference && o.firestore == firestore && o.path == path; + + @override + int get hashCode => hashList(_pathComponents); + + /// Parent returns the containing [CollectionReference]. + CollectionReference parent() { + return CollectionReference( + firestore, + (List.from(_pathComponents)..removeLast()), + ); + } + + /// Slash-delimited path representing the database location of this query. + String get path => _pathComponents.join('/'); + + /// This document's given or generated ID in the collection. + String get documentID => _pathComponents.last; + + /// Writes to the document referred to by this [DocumentReference]. + /// + /// If the document does not yet exist, it will be created. + /// + /// If [merge] is true, the provided data will be merged into an + /// existing document instead of overwriting. + Future setData(Map data, {bool merge = false}) { + throw UnimplementedError("setData() is not implemented"); + } + + /// Updates fields in the document referred to by this [DocumentReference]. + /// + /// Values in [data] may be of any supported Firestore type as well as + /// special sentinel [FieldValue] type. + /// + /// If no document exists yet, the update will fail. + Future updateData(Map data) { + throw UnimplementedError("updateData() is not implemented"); + } + + /// Reads the document referenced by this [DocumentReference]. + /// + /// If no document exists, the read will return null. + Future get({Source source = Source.serverAndCache}) async { + throw UnimplementedError("get() is not implemented"); + } + + /// Deletes the document referred to by this [DocumentReference]. + Future delete() { + throw UnimplementedError("delete() is not implemented"); + } + + /// Returns the reference of a collection contained inside of this + /// document. + CollectionReference collection(String collectionPath) { + return firestore.collection( + [path, collectionPath].join('/'), + ); + } + + /// Notifies of documents at this location + Stream snapshots({bool includeMetadataChanges = false}) { + throw UnimplementedError("snapshots() is not implemented"); + } +} \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart new file mode 100644 index 000000000000..79d352f0a394 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -0,0 +1,45 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A DocumentSnapshot contains data read from a document in your Firestore +/// database. +/// +/// The data can be extracted with the data property or by using subscript +/// syntax to access a specific field. +class DocumentSnapshot { + DocumentSnapshot(this._path, this.data, this.metadata, this._firestore); + + final String _path; + final FirestorePlatform _firestore; + + /// The reference that produced this snapshot + DocumentReference get reference => _firestore.document(_path); + + /// Contains all the data of this snapshot + final Map data; + + /// Metadata about this snapshot concerning its source and if it has local + /// modifications. + final SnapshotMetadata metadata; + + /// Reads individual values from the snapshot + dynamic operator [](String key) => data[key]; + + /// Returns the ID of the snapshot's document + String get documentID => _path.split('/').last; + + /// Returns `true` if the document exists. + bool get exists => data != null; +} + +Map _asStringKeyedMap(Map map) { + if (map == null) return null; + if (map is Map) { + return map; + } else { + return Map.from(map); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart new file mode 100644 index 000000000000..f3cd6c8ba205 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -0,0 +1,21 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +enum _FieldPathType { + documentId, +} + +/// A [FieldPath] refers to a field in a document. +class FieldPath { + const FieldPath._(this.type); + + @visibleForTesting + final _FieldPathType type; + + /// The path to the document id, which can be used in queries. + static FieldPath get documentId => + const FieldPath._(_FieldPathType.documentId); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart new file mode 100644 index 000000000000..534dfe49c43f --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart @@ -0,0 +1,68 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +@visibleForTesting +enum FieldValueType { + arrayUnion, + arrayRemove, + delete, + serverTimestamp, + incrementDouble, + incrementInteger, +} + +/// Sentinel values that can be used when writing document fields with set() or +/// update(). +class FieldValue { + FieldValue._(this.type, this.value); + + @visibleForTesting + final FieldValueType type; + + @visibleForTesting + final dynamic value; + + /// Returns a special value that tells the server to union the given elements + /// with any array value that already exists on the server. + /// + /// Each specified element that doesn't already exist in the array will be + /// added to the end. If the field being modified is not already an array it + /// will be overwritten with an array containing exactly the specified + /// elements. + static FieldValue arrayUnion(List elements) => + FieldValue._(FieldValueType.arrayUnion, elements); + + /// Returns a special value that tells the server to remove the given + /// elements from any array value that already exists on the server. + /// + /// All instances of each element specified will be removed from the array. + /// If the field being modified is not already an array it will be overwritten + /// with an empty array. + static FieldValue arrayRemove(List elements) => + FieldValue._(FieldValueType.arrayRemove, elements); + + /// Returns a sentinel for use with update() to mark a field for deletion. + static FieldValue delete() => FieldValue._(FieldValueType.delete, null); + + /// Returns a sentinel for use with set() or update() to include a + /// server-generated timestamp in the written data. + static FieldValue serverTimestamp() => + FieldValue._(FieldValueType.serverTimestamp, null); + + /// Returns a special value for use with set() or update() that tells the + /// server to increment the field’s current value by the given value. + static FieldValue increment(num value) { + // It is a compile-time error for any type other than int or double to + // attempt to extend or implement num. + assert(value is int || value is double); + if (value is double) { + return FieldValue._(FieldValueType.incrementDouble, value); + } else if (value is int) { + return FieldValue._(FieldValueType.incrementInteger, value); + } + return null; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart new file mode 100644 index 000000000000..c4fd46e98e6d --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -0,0 +1,124 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +@visibleForTesting +class FirestoreMessageCodec extends StandardMessageCodec { + const FirestoreMessageCodec(); + + static const int _kDateTime = 128; + static const int _kGeoPoint = 129; + static const int _kDocumentReference = 130; + static const int _kBlob = 131; + static const int _kArrayUnion = 132; + static const int _kArrayRemove = 133; + static const int _kDelete = 134; + static const int _kServerTimestamp = 135; + static const int _kTimestamp = 136; + static const int _kIncrementDouble = 137; + static const int _kIncrementInteger = 138; + static const int _kDocumentId = 139; + + static const Map _kFieldValueCodes = + { + FieldValueType.arrayUnion: _kArrayUnion, + FieldValueType.arrayRemove: _kArrayRemove, + FieldValueType.delete: _kDelete, + FieldValueType.serverTimestamp: _kServerTimestamp, + FieldValueType.incrementDouble: _kIncrementDouble, + FieldValueType.incrementInteger: _kIncrementInteger, + }; + + static const Map<_FieldPathType, int> _kFieldPathCodes = + <_FieldPathType, int>{ + _FieldPathType.documentId: _kDocumentId, + }; + + @override + void writeValue(WriteBuffer buffer, dynamic value) { + if (value is DateTime) { + buffer.putUint8(_kDateTime); + buffer.putInt64(value.millisecondsSinceEpoch); + } else if (value is Timestamp) { + buffer.putUint8(_kTimestamp); + buffer.putInt64(value.seconds); + buffer.putInt32(value.nanoseconds); + } else if (value is GeoPoint) { + buffer.putUint8(_kGeoPoint); + buffer.putFloat64(value.latitude); + buffer.putFloat64(value.longitude); + } else if (value is DocumentReference) { + buffer.putUint8(_kDocumentReference); + final List appName = utf8.encoder.convert(value.firestore.appName()); + writeSize(buffer, appName.length); + buffer.putUint8List(appName); + final List bytes = utf8.encoder.convert(value.path); + writeSize(buffer, bytes.length); + buffer.putUint8List(bytes); + } else if (value is Blob) { + buffer.putUint8(_kBlob); + writeSize(buffer, value.bytes.length); + buffer.putUint8List(value.bytes); + } else if (value is FieldValue) { + final int code = _kFieldValueCodes[value.type]; + assert(code != null); + buffer.putUint8(code); + if (value.value != null) writeValue(buffer, value.value); + } else if (value is FieldPath) { + final int code = _kFieldPathCodes[value.type]; + assert(code != null); + buffer.putUint8(code); + } else { + super.writeValue(buffer, value); + } + } + + @override + dynamic readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case _kDateTime: + return DateTime.fromMillisecondsSinceEpoch(buffer.getInt64()); + case _kTimestamp: + return Timestamp(buffer.getInt64(), buffer.getInt32()); + case _kGeoPoint: + return GeoPoint(buffer.getFloat64(), buffer.getFloat64()); + case _kDocumentReference: + final int appNameLength = readSize(buffer); + final String appName = + utf8.decoder.convert(buffer.getUint8List(appNameLength)); + //TODO(amr): Fix this. AppName should be used +// final FirebaseCorePlatform app = FirebaseCorePlatform.instance.appNamed(name: appName); + final FirestorePlatform firestore = FirestorePlatform.instance; + final int pathLength = readSize(buffer); + final String path = + utf8.decoder.convert(buffer.getUint8List(pathLength)); + return firestore.document(path); + case _kBlob: + final int length = readSize(buffer); + final List bytes = buffer.getUint8List(length); + return Blob(bytes); + case _kArrayUnion: + final List value = readValue(buffer); + return FieldValue.arrayUnion(value); + case _kArrayRemove: + final List value = readValue(buffer); + return FieldValue.arrayRemove(value); + case _kDelete: + return FieldValue.delete(); + case _kServerTimestamp: + return FieldValue.serverTimestamp(); + case _kIncrementDouble: + final double value = readValue(buffer); + return FieldValue.increment(value); + case _kIncrementInteger: + final int value = readValue(buffer); + return FieldValue.increment(value); + case _kDocumentId: + return FieldPath.documentId; + default: + return super.readValueOfType(type, buffer); + } + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart new file mode 100644 index 000000000000..d325d72e0a78 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -0,0 +1,19 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +class GeoPoint { + const GeoPoint(this.latitude, this.longitude); + + final double latitude; + final double longitude; + + @override + bool operator ==(dynamic o) => + o is GeoPoint && o.latitude == latitude && o.longitude == longitude; + + @override + int get hashCode => hashValues(latitude, longitude); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart new file mode 100644 index 000000000000..adca1ed6e6ad --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart @@ -0,0 +1,46 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A CollectionReference object can be used for adding documents, getting +/// document references, and querying for documents (using the methods +/// inherited from [Query]). +class MethodChannelCollectionReference extends CollectionReference { + MethodChannelCollectionReference(FirestorePlatform firestore, List pathComponents) + : super(firestore,pathComponents); + + /// ID of the referenced collection. + String get id => _pathComponents.isEmpty ? null : _pathComponents.last; + + @override + DocumentReference parent() { + if (_pathComponents.length < 2) { + return null; + } + return MethodChannelDocumentReference( + firestore, + (List.from(_pathComponents)..removeLast()), + ); + } + + @override + DocumentReference document([String path]) { + List childPath; + if (path == null) { + final String key = AutoIdGenerator.autoId(); + childPath = List.from(_pathComponents)..add(key); + } else { + childPath = List.from(_pathComponents)..addAll(path.split(('/'))); + } + return MethodChannelDocumentReference(firestore, childPath); + } + + @override + Future add(Map data) async { + final DocumentReference newDocument = document(); + await newDocument.setData(data); + return newDocument; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart new file mode 100644 index 000000000000..8d42bc4950f5 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -0,0 +1,134 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// The entry point for accessing a Firestore. +/// +/// You can get an instance by calling [Firestore.instance]. +class MethodChannelFirestore extends FirestorePlatform { + final FirebaseApp app; + + MethodChannelFirestore({FirebaseApp app}) + : this.app = app ?? FirebaseApp.instance { + if (_initialized) return; + channel.setMethodCallHandler((MethodCall call) async { + if (call.method == 'QuerySnapshot') { + final QuerySnapshot snapshot = QuerySnapshot._(call.arguments, this); + _queryObservers[call.arguments['handle']].add(snapshot); + } else if (call.method == 'DocumentSnapshot') { + final DocumentSnapshot snapshot = DocumentSnapshot( + call.arguments['path'], + _asStringKeyedMap(call.arguments['data']), + SnapshotMetadata(call.arguments['metadata']['hasPendingWrites'], + call.arguments['metadata']['isFromCache']), + this, + ); + _documentObservers[call.arguments['handle']].add(snapshot); + } else if (call.method == 'DoTransaction') { + final int transactionId = call.arguments['transactionId']; + final Transaction transaction = Transaction(transactionId, this); + final dynamic result = + await _transactionHandlers[transactionId](transaction); + await transaction._finish(); + return result; + } + }); + _initialized = true; + } + + /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. + /// + /// If null, the default [FirebaseApp] is used. + + static bool _initialized = false; + + @visibleForTesting + static const MethodChannel channel = MethodChannel( + 'plugins.flutter.io/cloud_firestore', + StandardMethodCodec(FirestoreMessageCodec()), + ); + + static final Map> _queryObservers = + >{}; + + static final Map> _documentObservers = + >{}; + + static final Map _transactionHandlers = + {}; + static int _transactionHandlerId = 0; + + @override + CollectionReference collection(String path) { + assert(path != null); + return CollectionReference(this, path.split('/')); + } + + @override + Query collectionGroup(String path) { + assert(path != null); + assert(!path.contains("/"), "Collection IDs must not contain '/'."); + return Query( + firestore: this, + isCollectionGroup: true, + pathComponents: path.split('/'), + ); + } + + @override + DocumentReference document(String path) { + assert(path != null); + return DocumentReference(this, path.split('/')); + } + + @override + WriteBatch batch() => WriteBatch(this); + + @override + Future> runTransaction( + TransactionHandler transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) async { + assert(timeout.inMilliseconds > 0, + 'Transaction timeout must be more than 0 milliseconds'); + final int transactionId = _transactionHandlerId++; + _transactionHandlers[transactionId] = transactionHandler; + final Map result = await channel + .invokeMapMethod( + 'Firestore#runTransaction', { + 'app': app.name, + 'transactionId': transactionId, + 'transactionTimeout': timeout.inMilliseconds + }); + return result ?? {}; + } + + @override + Future enablePersistence(bool enable) async { + assert(enable != null); + await channel + .invokeMethod('Firestore#enablePersistence', { + 'app': app.name, + 'enable': enable, + }); + } + + @override + Future settings( + {bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) async { + await channel.invokeMethod('Firestore#settings', { + 'app': app.name, + 'persistenceEnabled': persistenceEnabled, + 'host': host, + 'sslEnabled': sslEnabled, + 'cacheSizeBytes': cacheSizeBytes, + }); + } + + @override + String appName() => app.name; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart new file mode 100644 index 000000000000..c24526a089ce --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart @@ -0,0 +1,71 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// Represents a query over the data at a particular location. +class Query extends QueryPlatform{ + Query( + {@required FirestorePlatform firestore, + @required List pathComponents, + bool isCollectionGroup = false, + Map parameters}) + :super._(firestore: firestore, pathComponents: pathComponents, isCollectionGroup: isCollectionGroup, parameters: parameters); + + + // TODO(jackson): Reduce code duplication with [DocumentReference] + @override + Stream snapshots({bool includeMetadataChanges = false}) { + assert(includeMetadataChanges != null); + Future _handle; + // It's fine to let the StreamController be garbage collected once all the + // subscribers have cancelled; this analyzer warning is safe to ignore. + StreamController controller; // ignore: close_sinks + controller = StreamController.broadcast( + onListen: () { + _handle = MethodChannelFirestore.channel.invokeMethod( + 'Query#addSnapshotListener', + { + 'app': firestore.appName(), + 'path': _path, + 'isCollectionGroup': _isCollectionGroup, + 'parameters': _parameters, + 'includeMetadataChanges': includeMetadataChanges, + }, + ).then((dynamic result) => result); + _handle.then((int handle) { + MethodChannelFirestore._queryObservers[handle] = controller; + }); + }, + onCancel: () { + _handle.then((int handle) async { + await MethodChannelFirestore.channel.invokeMethod( + 'removeListener', + {'handle': handle}, + ); + MethodChannelFirestore._queryObservers.remove(handle); + }); + }, + ); + return controller.stream; + } + + /// Fetch the documents for this query + Future getDocuments( + {Source source = Source.serverAndCache}) async { + assert(source != null); + final Map data = + await MethodChannelFirestore.channel.invokeMapMethod( + 'Query#getDocuments', + { + 'app': firestore.appName(), + 'path': _path, + 'isCollectionGroup': _isCollectionGroup, + 'parameters': _parameters, + 'source': _getSourceString(source), + }, + ); + return QuerySnapshot._(data, firestore); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart new file mode 100644 index 000000000000..d82c949f2aa2 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart @@ -0,0 +1,381 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// Represents a query over the data at a particular location. +abstract class QueryPlatform { + QueryPlatform._( + {@required this.firestore, + @required List pathComponents, + bool isCollectionGroup = false, + Map parameters}) + : _pathComponents = pathComponents, + _isCollectionGroup = isCollectionGroup, + _parameters = parameters ?? + Map.unmodifiable({ + 'where': List>.unmodifiable(>[]), + 'orderBy': List>.unmodifiable(>[]), + }), + assert(firestore != null), + assert(pathComponents != null); + + /// The Firestore instance associated with this query + final FirestorePlatform firestore; + + final List _pathComponents; + final Map _parameters; + final bool _isCollectionGroup; + + String get _path => _pathComponents.join('/'); + + Query _copyWithParameters(Map parameters) { + return Query( + firestore: firestore, + isCollectionGroup: _isCollectionGroup, + pathComponents: _pathComponents, + parameters: Map.unmodifiable( + Map.from(_parameters)..addAll(parameters), + ), + ); + } + + Map buildArguments() { + return Map.from(_parameters) + ..addAll({ + 'path': _path, + }); + } + + /// Notifies of query results at this location + Stream snapshots({bool includeMetadataChanges = false}) { + throw UnimplementedError("snapshots() is not implemented"); + } + + /// Fetch the documents for this query + Future getDocuments( + {Source source = Source.serverAndCache}) async { + throw UnimplementedError("getDocuments() is not implemented"); + } + + /// Obtains a CollectionReference corresponding to this query's location. + CollectionReference reference() => + CollectionReference(firestore, _pathComponents); + + /// Creates and returns a new [Query] with additional filter on specified + /// [field]. [field] refers to a field in a document. + /// + /// The [field] may be a [String] consisting of a single field name + /// (referring to a top level field in the document), + /// or a series of field names separated by dots '.' + /// (referring to a nested field in the document). + /// Alternatively, the [field] can also be a [FieldPath]. + /// + /// Only documents satisfying provided condition are included in the result + /// set. + Query where( + dynamic field, { + dynamic isEqualTo, + dynamic isLessThan, + dynamic isLessThanOrEqualTo, + dynamic isGreaterThan, + dynamic isGreaterThanOrEqualTo, + dynamic arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + + final ListEquality equality = const ListEquality(); + final List> conditions = + List>.from(_parameters['where']); + + void addCondition(dynamic field, String operator, dynamic value) { + final List condition = [field, operator, value]; + assert( + conditions + .where((List item) => equality.equals(condition, item)) + .isEmpty, + 'Condition $condition already exists in this query.'); + conditions.add(condition); + } + + if (isEqualTo != null) addCondition(field, '==', isEqualTo); + if (isLessThan != null) addCondition(field, '<', isLessThan); + if (isLessThanOrEqualTo != null) + addCondition(field, '<=', isLessThanOrEqualTo); + if (isGreaterThan != null) addCondition(field, '>', isGreaterThan); + if (isGreaterThanOrEqualTo != null) + addCondition(field, '>=', isGreaterThanOrEqualTo); + if (arrayContains != null) + addCondition(field, 'array-contains', arrayContains); + if (arrayContainsAny != null) + addCondition(field, 'array-contains-any', arrayContainsAny); + if (whereIn != null) addCondition(field, 'in', whereIn); + if (isNull != null) { + assert( + isNull, + 'isNull can only be set to true. ' + 'Use isEqualTo to filter on non-null values.'); + addCondition(field, '==', null); + } + + return _copyWithParameters({'where': conditions}); + } + + /// Creates and returns a new [Query] that's additionally sorted by the specified + /// [field]. + /// The field may be a [String] representing a single field name or a [FieldPath]. + /// + /// After a [FieldPath.documentId] order by call, you cannot add any more [orderBy] + /// calls. + /// Furthermore, you may not use [orderBy] on the [FieldPath.documentId] [field] when + /// using [startAfterDocument], [startAtDocument], [endAfterDocument], + /// or [endAtDocument] because the order by clause on the document id + /// is added by these methods implicitly. + Query orderBy(dynamic field, {bool descending = false}) { + assert(field != null && descending != null); + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + + final List> orders = + List>.from(_parameters['orderBy']); + + final List order = [field, descending]; + assert(orders.where((List item) => field == item[0]).isEmpty, + 'OrderBy $field already exists in this query'); + + assert(() { + if (field == FieldPath.documentId) { + return !(_parameters.containsKey('startAfterDocument') || + _parameters.containsKey('startAtDocument') || + _parameters.containsKey('endAfterDocument') || + _parameters.containsKey('endAtDocument')); + } + return true; + }(), + '{start/end}{At/After/Before}Document order by document id themselves. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); + + orders.add(order); + return _copyWithParameters({'orderBy': orders}); + } + + /// Creates and returns a new [Query] that starts after the provided document + /// (exclusive). The starting position is relative to the order of the query. + /// The document must contain all of the fields provided in the orderBy of + /// this query. + /// + /// Cannot be used in combination with [startAtDocument], [startAt], or + /// [startAfter], but can be used in combination with [endAt], + /// [endBefore], [endAtDocument] and [endBeforeDocument]. + /// + /// See also: + /// + /// * [endAfterDocument] for a query that ends after a document. + /// * [startAtDocument] for a query that starts at a document. + /// * [endAtDocument] for a query that ends at a document. + Query startAfterDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!_parameters.containsKey('startAfter')); + assert(!_parameters.containsKey('startAt')); + assert(!_parameters.containsKey('startAfterDocument')); + assert(!_parameters.containsKey('startAtDocument')); + assert( + List>.from(_parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAfterDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); + return _copyWithParameters({ + 'startAfterDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + } + }); + } + + /// Creates and returns a new [Query] that starts at the provided document + /// (inclusive). The starting position is relative to the order of the query. + /// The document must contain all of the fields provided in the orderBy of + /// this query. + /// + /// Cannot be used in combination with [startAfterDocument], [startAfter], or + /// [startAt], but can be used in combination with [endAt], + /// [endBefore], [endAtDocument] and [endBeforeDocument]. + /// + /// See also: + /// + /// * [startAfterDocument] for a query that starts after a document. + /// * [endAtDocument] for a query that ends at a document. + /// * [endBeforeDocument] for a query that ends before a document. + Query startAtDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!_parameters.containsKey('startAfter')); + assert(!_parameters.containsKey('startAt')); + assert(!_parameters.containsKey('startAfterDocument')); + assert(!_parameters.containsKey('startAtDocument')); + assert( + List>.from(_parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAtDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); + return _copyWithParameters({ + 'startAtDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + }, + }); + } + + /// Takes a list of [values], creates and returns a new [Query] that starts + /// after the provided fields relative to the order of the query. + /// + /// The [values] must be in order of [orderBy] filters. + /// + /// Cannot be used in combination with [startAt], [startAfterDocument], or + /// [startAtDocument], but can be used in combination with [endAt], + /// [endBefore], [endAtDocument] and [endBeforeDocument]. + Query startAfter(List values) { + assert(values != null); + assert(!_parameters.containsKey('startAfter')); + assert(!_parameters.containsKey('startAt')); + assert(!_parameters.containsKey('startAfterDocument')); + assert(!_parameters.containsKey('startAtDocument')); + return _copyWithParameters({'startAfter': values}); + } + + /// Takes a list of [values], creates and returns a new [Query] that starts at + /// the provided fields relative to the order of the query. + /// + /// The [values] must be in order of [orderBy] filters. + /// + /// Cannot be used in combination with [startAfter], [startAfterDocument], + /// or [startAtDocument], but can be used in combination with [endAt], + /// [endBefore], [endAtDocument] and [endBeforeDocument]. + Query startAt(List values) { + assert(values != null); + assert(!_parameters.containsKey('startAfter')); + assert(!_parameters.containsKey('startAt')); + assert(!_parameters.containsKey('startAfterDocument')); + assert(!_parameters.containsKey('startAtDocument')); + return _copyWithParameters({'startAt': values}); + } + + /// Creates and returns a new [Query] that ends at the provided document + /// (inclusive). The end position is relative to the order of the query. + /// The document must contain all of the fields provided in the orderBy of + /// this query. + /// + /// Cannot be used in combination with [endBefore], [endBeforeDocument], or + /// [endAt], but can be used in combination with [startAt], + /// [startAfter], [startAtDocument] and [startAfterDocument]. + /// + /// See also: + /// + /// * [startAfterDocument] for a query that starts after a document. + /// * [startAtDocument] for a query that starts at a document. + /// * [endBeforeDocument] for a query that ends before a document. + Query endAtDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!_parameters.containsKey('endBefore')); + assert(!_parameters.containsKey('endAt')); + assert(!_parameters.containsKey('endBeforeDocument')); + assert(!_parameters.containsKey('endAtDocument')); + assert( + List>.from(_parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endAtDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); + return _copyWithParameters({ + 'endAtDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + }, + }); + } + + /// Takes a list of [values], creates and returns a new [Query] that ends at the + /// provided fields relative to the order of the query. + /// + /// The [values] must be in order of [orderBy] filters. + /// + /// Cannot be used in combination with [endBefore], [endBeforeDocument], or + /// [endAtDocument], but can be used in combination with [startAt], + /// [startAfter], [startAtDocument] and [startAfterDocument]. + Query endAt(List values) { + assert(values != null); + assert(!_parameters.containsKey('endBefore')); + assert(!_parameters.containsKey('endAt')); + assert(!_parameters.containsKey('endBeforeDocument')); + assert(!_parameters.containsKey('endAtDocument')); + return _copyWithParameters({'endAt': values}); + } + + /// Creates and returns a new [Query] that ends before the provided document + /// (exclusive). The end position is relative to the order of the query. + /// The document must contain all of the fields provided in the orderBy of + /// this query. + /// + /// Cannot be used in combination with [endAt], [endBefore], or + /// [endAtDocument], but can be used in combination with [startAt], + /// [startAfter], [startAtDocument] and [startAfterDocument]. + /// + /// See also: + /// + /// * [startAfterDocument] for a query that starts after document. + /// * [startAtDocument] for a query that starts at a document. + /// * [endAtDocument] for a query that ends at a document. + Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!_parameters.containsKey('endBefore')); + assert(!_parameters.containsKey('endAt')); + assert(!_parameters.containsKey('endBeforeDocument')); + assert(!_parameters.containsKey('endAtDocument')); + assert( + List>.from(_parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endBeforeDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); + return _copyWithParameters({ + 'endBeforeDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data, + }, + }); + } + + /// Takes a list of [values], creates and returns a new [Query] that ends before + /// the provided fields relative to the order of the query. + /// + /// The [values] must be in order of [orderBy] filters. + /// + /// Cannot be used in combination with [endAt], [endBeforeDocument], or + /// [endBeforeDocument], but can be used in combination with [startAt], + /// [startAfter], [startAtDocument] and [startAfterDocument]. + Query endBefore(List values) { + assert(values != null); + assert(!_parameters.containsKey('endBefore')); + assert(!_parameters.containsKey('endAt')); + assert(!_parameters.containsKey('endBeforeDocument')); + assert(!_parameters.containsKey('endAtDocument')); + return _copyWithParameters({'endBefore': values}); + } + + /// Creates and returns a new Query that's additionally limited to only return up + /// to the specified number of documents. + Query limit(int length) { + assert(!_parameters.containsKey('limit')); + return _copyWithParameters({'limit': length}); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart new file mode 100644 index 000000000000..df6ccf7567e0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart @@ -0,0 +1,42 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A QuerySnapshot contains zero or more DocumentSnapshot objects. +class QuerySnapshot { + QuerySnapshot._(Map data, FirestorePlatform firestore) + : documents = List.generate(data['documents'].length, + (int index) { + return DocumentSnapshot( + data['paths'][index], + _asStringKeyedMap(data['documents'][index]), + SnapshotMetadata( + data['metadatas'][index]['hasPendingWrites'], + data['metadatas'][index]['isFromCache'], + ), + firestore, + ); + }), + documentChanges = List.generate( + data['documentChanges'].length, (int index) { + return DocumentChange._( + data['documentChanges'][index], + firestore, + ); + }), + metadata = SnapshotMetadata( + data['metadata']['hasPendingWrites'], + data['metadata']['isFromCache'], + ); + + /// Gets a list of all the documents included in this snapshot + final List documents; + + /// An array of the documents that changed since the last snapshot. If this + /// is the first snapshot, all documents will be in the list as Added changes. + final List documentChanges; + + final SnapshotMetadata metadata; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart new file mode 100644 index 000000000000..2f9a6104a9e5 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart @@ -0,0 +1,28 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// Metadata about a snapshot, describing the state of the snapshot. +class SnapshotMetadata { + SnapshotMetadata(this.hasPendingWrites, this.isFromCache); + + /// Whether the snapshot contains the result of local writes that have not yet + /// been committed to the backend. + /// + /// If you called [DocumentReference.snapshots] or [Query.snapshots] with + /// `includeMetadataChanges` parameter set to `true` you will receive another + /// snapshot with `hasPendingWrites` equal to `false` once the writes have been + /// committed to the backend. + final bool hasPendingWrites; + + /// Whether the snapshot was created from cached data rather than guaranteed + /// up-to-date server data. + /// + /// If you called [DocumentReference.snapshots] or [Query.snapshots] with + /// `includeMetadataChanges` parameter set to `true` you will receive another + /// snapshot with `isFomCache` equal to `false` once the client has received + /// up-to-date data from the backend. + final bool isFromCache; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart new file mode 100644 index 000000000000..764a02f4d21f --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart @@ -0,0 +1,37 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// An enumeration of firestore source types. +enum Source { + /// Causes Firestore to try to retrieve an up-to-date (server-retrieved) snapshot, but fall back to + /// returning cached data if the server can't be reached. + serverAndCache, + + /// Causes Firestore to avoid the cache, generating an error if the server cannot be reached. Note + /// that the cache will still be updated if the server request succeeds. Also note that + /// latency-compensation still takes effect, so any pending write operations will be visible in the + /// returned data (merged into the server-provided data). + server, + + /// Causes Firestore to immediately return a value from the cache, ignoring the server completely + /// (implying that the returned value may be stale with respect to the value on the server). If + /// there is no data in the cache to satisfy the [get()] or [getDocuments()] call, + /// [DocumentReference.get()] will return an error and [Query.getDocuments()] will return an empty + /// [QuerySnapshot] with no documents. + cache, +} + +/// Converts [Source] to [String] +String _getSourceString(Source source) { + assert(source != null); + if (source == Source.server) { + return 'server'; + } + if (source == Source.cache) { + return 'cache'; + } + return 'default'; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart new file mode 100644 index 000000000000..06700468aa54 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart @@ -0,0 +1,98 @@ +// Copyright 2018, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +const int _kThousand = 1000; +const int _kMillion = 1000000; +const int _kBillion = 1000000000; + +void _check(bool expr, String name, int value) { + if (!expr) { + throw ArgumentError("Timestamp $name out of range: $value"); + } +} + +/// A Timestamp represents a point in time independent of any time zone or calendar, +/// represented as seconds and fractions of seconds at nanosecond resolution in UTC +/// Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends +/// the Gregorian calendar backwards to year one. It is encoded assuming all minutes +/// are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second table +/// is needed for interpretation. Range is from 0001-01-01T00:00:00Z to +/// 9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we +/// can convert to and from RFC 3339 date strings. +/// +/// For more information, see [the reference timestamp definition](https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto) +class Timestamp implements Comparable { + Timestamp(this._seconds, this._nanoseconds) { + _validateRange(_seconds, _nanoseconds); + } + + factory Timestamp.fromMillisecondsSinceEpoch(int milliseconds) { + final int seconds = (milliseconds / _kThousand).floor(); + final int nanoseconds = (milliseconds - seconds * _kThousand) * _kMillion; + return Timestamp(seconds, nanoseconds); + } + + factory Timestamp.fromMicrosecondsSinceEpoch(int microseconds) { + final int seconds = (microseconds / _kMillion).floor(); + final int nanoseconds = (microseconds - seconds * _kMillion) * _kThousand; + return Timestamp(seconds, nanoseconds); + } + + factory Timestamp.fromDate(DateTime date) { + return Timestamp.fromMicrosecondsSinceEpoch(date.microsecondsSinceEpoch); + } + + factory Timestamp.now() { + return Timestamp.fromMicrosecondsSinceEpoch( + DateTime.now().microsecondsSinceEpoch); + } + + final int _seconds; + final int _nanoseconds; + + static const int _kStartOfTime = -62135596800; + static const int _kEndOfTime = 253402300800; + + int get seconds => _seconds; + + int get nanoseconds => _nanoseconds; + + int get millisecondsSinceEpoch => + (seconds * _kThousand + nanoseconds / _kMillion).floor(); + + int get microsecondsSinceEpoch => + (seconds * _kMillion + nanoseconds / _kThousand).floor(); + + DateTime toDate() { + return DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch); + } + + @override + int get hashCode => hashValues(seconds, nanoseconds); + @override + bool operator ==(dynamic o) => + o is Timestamp && o.seconds == seconds && o.nanoseconds == nanoseconds; + @override + int compareTo(Timestamp other) { + if (seconds == other.seconds) { + return nanoseconds.compareTo(other.nanoseconds); + } + + return seconds.compareTo(other.seconds); + } + + @override + String toString() { + return "Timestamp(seconds=$seconds, nanoseconds=$nanoseconds)"; + } + + static void _validateRange(int seconds, int nanoseconds) { + _check(nanoseconds >= 0, 'nanoseconds', nanoseconds); + _check(nanoseconds < _kBillion, 'nanoseconds', nanoseconds); + _check(seconds >= _kStartOfTime, 'seconds', seconds); + _check(seconds < _kEndOfTime, 'seconds', seconds); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart new file mode 100644 index 000000000000..b59d3c459b0a --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -0,0 +1,65 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +class Transaction extends TransactionPlatform { + @visibleForTesting + Transaction(int transactionId, FirestorePlatform firestore) : super(transactionId, firestore); + + + @override + Future _get(DocumentReference documentReference) async { + final Map result = await MethodChannelFirestore.channel + .invokeMapMethod('Transaction#get', { + 'app': firestore.appName(), + 'transactionId': _transactionId, + 'path': documentReference.path, + }); + if (result != null) { + return DocumentSnapshot( + documentReference.path, + result['data']?.cast(), + SnapshotMetadata(result['metadata']['hasPendingWrites'], + result['metadata']['isFromCache']), + firestore); + } else { + return null; + } + } + + @override + Future _delete(DocumentReference documentReference) async { + return MethodChannelFirestore.channel + .invokeMethod('Transaction#delete', { + 'app': firestore.appName(), + 'transactionId': _transactionId, + 'path': documentReference.path, + }); + } + + @override + Future _update( + DocumentReference documentReference, Map data) async { + return MethodChannelFirestore.channel + .invokeMethod('Transaction#update', { + 'app': firestore.appName(), + 'transactionId': _transactionId, + 'path': documentReference.path, + 'data': data, + }); + } + + @override + Future _set( + DocumentReference documentReference, Map data) async { + return MethodChannelFirestore.channel + .invokeMethod('Transaction#set', { + 'app': firestore.appName(), + 'transactionId': _transactionId, + 'path': documentReference.path, + 'data': data, + }); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart new file mode 100644 index 000000000000..129cde52711f --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -0,0 +1,77 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +typedef Future TransactionHandler(Transaction transaction); + +abstract class TransactionPlatform { + @visibleForTesting + TransactionPlatform(this._transactionId, this.firestore); + + int _transactionId; + FirestorePlatform firestore; + List> _pendingResults = >[]; + Future _finish() => Future.wait(_pendingResults); + + /// Reads the document referenced by the provided DocumentReference. + Future get(DocumentReference documentReference) { + final Future result = _get(documentReference); + _pendingResults.add(result); + return result; + } + + Future _get(DocumentReference documentReference) async { + throw UnimplementedError("get() not implemented"); + } + + /// Deletes the document referred to by the provided [documentReference]. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. + Future delete(DocumentReference documentReference) { + final Future result = _delete(documentReference); + _pendingResults.add(result); + return result; + } + + Future _delete(DocumentReference documentReference) async { + throw UnimplementedError("delete() not implemented"); + } + + /// Updates fields in the document referred to by [documentReference]. + /// The update will fail if applied to a document that does not exist. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. + Future update( + DocumentReference documentReference, Map data) async { + final Future result = _update(documentReference, data); + _pendingResults.add(result); + return result; + } + + Future _update( + DocumentReference documentReference, Map data) async { + throw UnimplementedError("updated() not implemented"); + } + + /// Writes to the document referred to by the provided [DocumentReference]. + /// If the document does not exist yet, it will be created. If you pass + /// SetOptions, the provided data can be merged into the existing document. + /// + /// Awaiting the returned [Future] is optional and will be done automatically + /// when the transaction handler completes. + Future set( + DocumentReference documentReference, Map data) { + final Future result = _set(documentReference, data); + _pendingResults.add(result); + return result; + } + + Future _set( + DocumentReference documentReference, Map data) async { + throw UnimplementedError("set() not implemented"); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart new file mode 100644 index 000000000000..ea21cbea5cc5 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart @@ -0,0 +1,34 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// Utility class for generating Firebase child node keys. +/// +/// Since the Flutter plugin API is asynchronous, there's no way for us +/// to use the native SDK to generate the node key synchronously and we +/// have to do it ourselves if we want to be able to reference the +/// newly-created node synchronously. +/// +/// This code is based largely on the Android implementation and ported to Dart. + +class AutoIdGenerator { + static const int _AUTO_ID_LENGTH = 20; + + static const String _AUTO_ID_ALPHABET = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + static final Random _random = Random(); + + static String autoId() { + final StringBuffer stringBuffer = StringBuffer(); + final int maxRandom = _AUTO_ID_ALPHABET.length; + + for (int i = 0; i < _AUTO_ID_LENGTH; ++i) { + stringBuffer.write(_AUTO_ID_ALPHABET[_random.nextInt(maxRandom)]); + } + + return stringBuffer.toString(); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart new file mode 100644 index 000000000000..3fd9e517af61 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart @@ -0,0 +1,101 @@ +// Copyright 2018, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A [WriteBatch] is a series of write operations to be performed as one unit. +/// +/// Operations done on a [WriteBatch] do not take effect until you [commit]. +/// +/// Once committed, no further operations can be performed on the [WriteBatch], +/// nor can it be committed again. +class WriteBatch extends WriteBatchPlatform { + WriteBatch(this._firestore) + : _handle = MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#create', {'app': _firestore.appName()}), + super._(); + + final FirestorePlatform _firestore; + Future _handle; + final List> _actions = >[]; + + @override + Future commit() async { + if (!_committed) { + _committed = true; + await Future.wait(_actions); + await MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#commit', {'handle': await _handle}); + } else { + throw StateError("This batch has already been committed."); + } + } + + @override + void delete(DocumentReference document) { + if (!_committed) { + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#delete', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + }, + ), + ); + }); + } else { + throw StateError( + "This batch has been committed and can no longer be changed."); + } + } + + @override + void setData(DocumentReference document, Map data, + {bool merge = false}) { + if (!_committed) { + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#setData', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + 'data': data, + 'options': {'merge': merge}, + }, + ), + ); + }); + } else { + throw StateError( + "This batch has been committed and can no longer be changed."); + } + } + + @override + void updateData(DocumentReference document, Map data) { + if (!_committed) { + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#updateData', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + 'data': data, + }, + ), + ); + }); + } else { + throw StateError( + "This batch has been committed and can no longer be changed."); + } + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart new file mode 100644 index 000000000000..5bd2e5ef9396 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart @@ -0,0 +1,50 @@ +// Copyright 2018, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A [WriteBatch] is a series of write operations to be performed as one unit. +/// +/// Operations done on a [WriteBatch] do not take effect until you [commit]. +/// +/// Once committed, no further operations can be performed on the [WriteBatch], +/// nor can it be committed again. +abstract class WriteBatchPlatform { + WriteBatchPlatform._(); + + final List> _actions = >[]; + + /// Indicator to whether or not this [WriteBatch] has been committed. + bool _committed = false; + + /// Commits all of the writes in this write batch as a single atomic unit. + /// + /// Calling this method prevents any future operations from being added. + Future commit() async { + throw UnimplementedError("commit() not implemented"); + } + + /// Deletes the document referred to by [document]. + void delete(DocumentReference document) { + throw UnimplementedError("commit() not implemented"); + } + + /// Writes to the document referred to by [document]. + /// + /// If the document does not yet exist, it will be created. + /// + /// If [merge] is true, the provided data will be merged into an + /// existing document instead of overwriting. + void setData(DocumentReference document, Map data, + {bool merge = false}) { + throw UnimplementedError("commit() not implemented"); + } + + /// Updates fields in the document referred to by [document]. + /// + /// If the document does not exist, the operation will fail. + void updateData(DocumentReference document, Map data) { + throw UnimplementedError("commit() not implemented"); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..a5643ce810c7 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml @@ -0,0 +1,21 @@ +name: cloud_firestore_platform_interface +description: A common platform interface for the firebase_auth plugin. +version: 0.0.1 +homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_platform_interface + +dependencies: + flutter: + sdk: flutter + meta: ^1.0.5 + collection: ^1.14.3 + firebase_core: ^0.4.3+1 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^4.1.1 + +environment: + sdk: ">=2.0.0-dev.28.0 <3.0.0" + flutter: ">=1.9.1+hotfix.5 <2.0.0" + From 9ed7d8c7c471f823336ac3d6c075244ed9570330 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 14 Dec 2019 22:28:48 +0000 Subject: [PATCH 002/144] - Created cloud_firestore_web package --- .../cloud_firestore_web/CHANGELOG.md | 22 +++++++ .../cloud_firestore_web/LICENSE | 27 +++++++++ .../cloud_firestore_web/README.md | 52 +++++++++++++++++ .../cloud_firestore_web/analysis_options.yaml | 12 ++++ .../cloud_firestore_web/android/.gitignore | 8 +++ .../cloud_firestore_web/android/build.gradle | 33 +++++++++++ .../android/gradle.properties | 2 + .../gradle/wrapper/gradle-wrapper.properties | 5 ++ .../android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 3 + .../FirebaseAuthWebPlugin.java | 15 +++++ .../ios/firebase_auth_web.podspec | 21 +++++++ .../lib/collection_reference_web.dart | 47 +++++++++++++++ .../lib/document_reference_web.dart | 45 +++++++++++++++ .../lib/firestore_web.dart | 57 +++++++++++++++++++ .../cloud_firestore_web/pubspec.yaml | 36 ++++++++++++ 16 files changed, 386 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md create mode 100644 packages/cloud_firestore/cloud_firestore_web/LICENSE create mode 100644 packages/cloud_firestore/cloud_firestore_web/README.md create mode 100644 packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/.gitignore create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/build.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/settings.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java create mode 100644 packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/pubspec.yaml diff --git a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md new file mode 100644 index 000000000000..12ad56ba3fd6 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md @@ -0,0 +1,22 @@ +## 0.1.1+1 + +* Add an android/ folder with no-op implementation to workaround https://github.com/flutter/flutter/issues/46898 + +## 0.1.1 + +* Require Flutter SDK version 1.12.13+hotfix.4 or later. +* Add fake podspec so we don't break compilation on iOS. +* Fix homepage. + +## 0.1.0+2 + +* Remove the deprecated `author:` field from pubspec.yaml. +* Bump the minimum Flutter version to 1.10.0. + +## 0.1.0+1 + +* Fixed serialization error for creationTime and lastSignInTime being RFC 1123. + +## 0.1.0 + +* Initial open-source release. diff --git a/packages/cloud_firestore/cloud_firestore_web/LICENSE b/packages/cloud_firestore/cloud_firestore_web/LICENSE new file mode 100644 index 000000000000..000b4618d2bd --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2017 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. \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/README.md b/packages/cloud_firestore/cloud_firestore_web/README.md new file mode 100644 index 000000000000..f01d4b00f981 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/README.md @@ -0,0 +1,52 @@ +# firebase_auth_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_auth` +plugin. + +_(This is only temporary: in the future we hope to make this package +an "endorsed" implementation of `firebase_auth`, 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_auth: ^0.15.1 + firebase_auth_web: ^0.1.0 + ... +``` + +### Updating `index.html` + +Due to [this bug in dartdevc][2], you will need to manually add the Firebase +JavaScript files to your `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_auth_web` dependency to your pubspec, +you can use `package:firebase_auth` as normal. + +[1]: ../firebase_auth +[2]: https://github.com/dart-lang/sdk/issues/33979 diff --git a/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml new file mode 100644 index 000000000000..bbfa25e2146a --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml @@ -0,0 +1,12 @@ +# This is a temporary file to allow us to land a new set of linter rules in a +# series of manageable patches instead of one gigantic PR. It disables some of +# the new lints that are already failing on this plugin, for this plugin. It +# should be deleted and the failing lints addressed as soon as possible. + +include: ../../../analysis_options.yaml + +analyzer: + errors: + curly_braces_in_flow_control_structures: ignore + public_member_api_docs: ignore + unawaited_futures: ignore diff --git a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore new file mode 100644 index 000000000000..c6cbe562a427 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle new file mode 100644 index 000000000000..be4c5134dc6d --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle @@ -0,0 +1,33 @@ +group 'io.flutter.plugins.firebaseauth_web' +version '1.0' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties new file mode 100644 index 000000000000..3148384dab31 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..019065d1d650 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle new file mode 100644 index 000000000000..f091fd86b256 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'firebaseauth_web' diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..6f77c56a11e2 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java new file mode 100644 index 000000000000..2caff2952214 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java @@ -0,0 +1,15 @@ +package io.flutter.plugins.firebaseauth_web; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +/** FirebaseAuthWebPlugin */ +public class FirebaseAuthWebPlugin implements FlutterPlugin { + @Override + public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {} + + public static void registerWith(Registrar registrar) {} + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) {} +} diff --git a/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec b/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec new file mode 100644 index 000000000000..2a114b380720 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_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_auth_web' + s.version = '0.1.0' + s.summary = 'No-op implementation of firebase_auth_web web plugin to avoid build issues on iOS' + s.description = <<-DESC + temp fake firebase_auth_web plugin + DESC + s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_auth/firebase_auth_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/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart new file mode 100644 index 000000000000..0b262e49fbbc --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -0,0 +1,47 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/document_reference_web.dart'; +import 'package:firebase/firestore.dart' as web; + +class CollectionReferenceWeb extends CollectionReference { + final web.Firestore webFirestore; + final List _pathComponents; + + CollectionReferenceWeb( + this.webFirestore, FirestorePlatform firestore, this._pathComponents) + : super(firestore, _pathComponents); + + @override + DocumentReference parent() { + if (_pathComponents.length < 2) { + return null; + } + return DocumentReferenceWeb( + webFirestore, + firestore, + (List.from(_pathComponents)..removeLast()), + ); + } + + @override + DocumentReference document([String path]) { + List childPath; + if (path == null) { + final String key = AutoIdGenerator.autoId(); + childPath = List.from(_pathComponents)..add(key); + } else { + childPath = List.from(_pathComponents)..addAll(path.split(('/'))); + } + return DocumentReferenceWeb( + webFirestore, + firestore, + childPath, + ); + } + + @override + Future add(Map data) async { + final DocumentReference newDocument = document(); + await newDocument.setData(data); + return newDocument; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart new file mode 100644 index 000000000000..a73e77acaf62 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -0,0 +1,45 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +class DocumentReferenceWeb extends DocumentReference { + final web.Firestore firestoreWeb; + DocumentReferenceWeb(this.firestoreWeb,FirestorePlatform firestore, List pathComponents) + : super(firestore, pathComponents); + + @override + Future setData(Map data, {bool merge = false}) { + return firestoreWeb.doc(path).set(data, web.SetOptions(merge: merge)); + } + + @override + Future updateData(Map data) { + return firestoreWeb.doc(path).update(data: data); + } + + @override + Future get({Source source = Source.serverAndCache}) async { + return _fromWeb(await firestoreWeb.doc(path).get()); + } + + @override + Future delete() { + return firestoreWeb.doc(path).delete(); + } + + @override + Stream snapshots({bool includeMetadataChanges = false}) { + return firestoreWeb + .doc(path) + .onSnapshot + .map((web.DocumentSnapshot webSnapshot) => _fromWeb(webSnapshot)); + } + + DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + this.firestore); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart new file mode 100644 index 000000000000..7c27466fca76 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -0,0 +1,57 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/collection_reference_web.dart'; +import 'package:cloud_firestore_web/document_reference_web.dart'; +import 'package:firebase/firebase.dart' as firebase; +import 'package:firebase/firestore.dart' show Settings; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +class FirestoreWeb extends FirestorePlatform { + static void registerWith(Registrar registrar) { + FirestorePlatform.instance = FirestoreWeb(); + } + + FirestoreWeb() : super(); + + final app = firebase.firestore(); + + @override + CollectionReference collection(String path) => + CollectionReferenceWeb(app, this, path.split('/')); + + @override + Query collectionGroup(String path) => Query( + firestore: this, + isCollectionGroup: true, + pathComponents: path.split('/')); + + @override + DocumentReference document(String path) => + DocumentReferenceWeb(app, this, path.split('/')); + + @override + WriteBatch batch() => WriteBatch(this); + + @override + Future enablePersistence(bool enable) async { + if (enable) { + await app.enablePersistence(); + } + } + + @override + Future settings( + {bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) async { + return app.settings( + Settings(ssl: sslEnabled, cacheSizeBytes: cacheSizeBytes, host: host)); + } + + @override + Future> runTransaction(transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) async {} + + @override + String appName() => firebase.app().name; +} diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml new file mode 100644 index 000000000000..361702885dc3 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -0,0 +1,36 @@ +name: cloud_firestore_web +description: The web implementation of cloud_firestore +homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_web +version: 0.0.1 + +flutter: + plugin: + platforms: + web: + pluginClass: FirestoreWeb + fileName: firestore_web.dart + +dependencies: + flutter: + sdk: flutter + flutter_web_plugins: + sdk: flutter + firebase: ^7.0.0 + http_parser: ^3.1.3 + meta: ^1.1.7 + cloud_firestore_platform_interface: + path: ../cloud_firestore_platform_interface + js: ^0.6.1 + +dev_dependencies: + flutter_test: + sdk: flutter + cloud_firestore: + path: ../cloud_firestore + firebase_core_platform_interface: ^1.0.0 + firebase_core_web: ^0.1.1 + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4 <2.0.0" + From 7fdd1c86bfe56077e034f71b54d3dd59fe8d4b94 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 15 Dec 2019 20:38:34 +0000 Subject: [PATCH 003/144] Created query interface --- .../lib/src/collection_reference.dart | 8 +- .../method_channel_collection_reference.dart | 15 +- .../lib/src/method_channel_firestore.dart | 4 +- .../lib/src/query.dart | 31 ++-- .../lib/src/query_interface.dart | 143 +++++++++--------- .../lib/src/query_snapshot.dart | 2 +- .../lib/collection_reference_web.dart | 14 +- .../lib/firestore_web.dart | 3 +- .../cloud_firestore_web/lib/query_web.dart | 47 ++++++ 9 files changed, 158 insertions(+), 109 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart index c576d1646146..7f8ff592c62a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart @@ -12,7 +12,7 @@ class CollectionReference extends Query { : super(firestore: firestore, pathComponents: pathComponents); /// ID of the referenced collection. - String get id => _pathComponents.isEmpty ? null : _pathComponents.last; + String get id => pathComponents.isEmpty ? null : pathComponents.last; /// For subcollections, parent returns the containing [DocumentReference]. /// @@ -20,11 +20,7 @@ class CollectionReference extends Query { DocumentReference parent() { throw UnimplementedError("parent() is not implemented"); } - - /// A string containing the slash-separated path to this CollectionReference - /// (relative to the root of the database). - String get path => _path; - + /// Returns a `DocumentReference` with the provided path. /// /// If no [path] is provided, an auto-generated ID is used. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart index adca1ed6e6ad..20397f785225 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart @@ -7,21 +7,21 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [Query]). -class MethodChannelCollectionReference extends CollectionReference { +class MethodChannelCollectionReference extends QueryPlatform implements CollectionReference { MethodChannelCollectionReference(FirestorePlatform firestore, List pathComponents) - : super(firestore,pathComponents); + : super(firestore: firestore,pathComponents: pathComponents); /// ID of the referenced collection. - String get id => _pathComponents.isEmpty ? null : _pathComponents.last; + String get id => pathComponents.isEmpty ? null : pathComponents.last; @override DocumentReference parent() { - if (_pathComponents.length < 2) { + if (pathComponents.length < 2) { return null; } return MethodChannelDocumentReference( firestore, - (List.from(_pathComponents)..removeLast()), + (List.from(pathComponents)..removeLast()), ); } @@ -30,9 +30,9 @@ class MethodChannelCollectionReference extends CollectionReference { List childPath; if (path == null) { final String key = AutoIdGenerator.autoId(); - childPath = List.from(_pathComponents)..add(key); + childPath = List.from(pathComponents)..add(key); } else { - childPath = List.from(_pathComponents)..addAll(path.split(('/'))); + childPath = List.from(pathComponents)..addAll(path.split(('/'))); } return MethodChannelDocumentReference(firestore, childPath); } @@ -43,4 +43,5 @@ class MethodChannelCollectionReference extends CollectionReference { await newDocument.setData(data); return newDocument; } + } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 8d42bc4950f5..b74d3a2a8694 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -15,7 +15,7 @@ class MethodChannelFirestore extends FirestorePlatform { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { - final QuerySnapshot snapshot = QuerySnapshot._(call.arguments, this); + final QuerySnapshot snapshot = QuerySnapshot(call.arguments, this); _queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { final DocumentSnapshot snapshot = DocumentSnapshot( @@ -70,7 +70,7 @@ class MethodChannelFirestore extends FirestorePlatform { Query collectionGroup(String path) { assert(path != null); assert(!path.contains("/"), "Collection IDs must not contain '/'."); - return Query( + return QueryPlatform( firestore: this, isCollectionGroup: true, pathComponents: path.split('/'), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart index c24526a089ce..c128f1ea0545 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart @@ -5,14 +5,25 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -class Query extends QueryPlatform{ - Query( +class QueryPlatform extends Query{ + QueryPlatform( {@required FirestorePlatform firestore, @required List pathComponents, bool isCollectionGroup = false, Map parameters}) - :super._(firestore: firestore, pathComponents: pathComponents, isCollectionGroup: isCollectionGroup, parameters: parameters); + :super(firestore: firestore, pathComponents: pathComponents, isCollectionGroup: isCollectionGroup, parameters: parameters); + + Query copyWithParameters(Map parameters) { + return QueryPlatform( + firestore: firestore, + isCollectionGroup: isCollectionGroup, + pathComponents: pathComponents, + parameters: Map.unmodifiable( + Map.from(parameters)..addAll(parameters), + ), + ); + } // TODO(jackson): Reduce code duplication with [DocumentReference] @override @@ -28,9 +39,9 @@ class Query extends QueryPlatform{ 'Query#addSnapshotListener', { 'app': firestore.appName(), - 'path': _path, - 'isCollectionGroup': _isCollectionGroup, - 'parameters': _parameters, + 'path': path, + 'isCollectionGroup': isCollectionGroup, + 'parameters': parameters, 'includeMetadataChanges': includeMetadataChanges, }, ).then((dynamic result) => result); @@ -60,12 +71,12 @@ class Query extends QueryPlatform{ 'Query#getDocuments', { 'app': firestore.appName(), - 'path': _path, - 'isCollectionGroup': _isCollectionGroup, - 'parameters': _parameters, + 'path': path, + 'isCollectionGroup': isCollectionGroup, + 'parameters': parameters, 'source': _getSourceString(source), }, ); - return QuerySnapshot._(data, firestore); + return QuerySnapshot(data, firestore); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart index d82c949f2aa2..1468c1dcdcb1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart @@ -5,15 +5,15 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -abstract class QueryPlatform { - QueryPlatform._( +abstract class Query { + Query( {@required this.firestore, @required List pathComponents, bool isCollectionGroup = false, Map parameters}) - : _pathComponents = pathComponents, - _isCollectionGroup = isCollectionGroup, - _parameters = parameters ?? + : pathComponents = pathComponents, + isCollectionGroup = isCollectionGroup, + parameters = parameters ?? Map.unmodifiable({ 'where': List>.unmodifiable(>[]), 'orderBy': List>.unmodifiable(>[]), @@ -24,27 +24,20 @@ abstract class QueryPlatform { /// The Firestore instance associated with this query final FirestorePlatform firestore; - final List _pathComponents; - final Map _parameters; - final bool _isCollectionGroup; + final List pathComponents; + final Map parameters; + final bool isCollectionGroup; - String get _path => _pathComponents.join('/'); + String get path => pathComponents.join('/'); - Query _copyWithParameters(Map parameters) { - return Query( - firestore: firestore, - isCollectionGroup: _isCollectionGroup, - pathComponents: _pathComponents, - parameters: Map.unmodifiable( - Map.from(_parameters)..addAll(parameters), - ), - ); + Query copyWithParameters(Map parameters) { + throw UnimplementedError("copyWithParameters() is not implemented"); } Map buildArguments() { - return Map.from(_parameters) + return Map.from(parameters) ..addAll({ - 'path': _path, + 'path': path, }); } @@ -61,7 +54,7 @@ abstract class QueryPlatform { /// Obtains a CollectionReference corresponding to this query's location. CollectionReference reference() => - CollectionReference(firestore, _pathComponents); + CollectionReference(firestore, pathComponents); /// Creates and returns a new [Query] with additional filter on specified /// [field]. [field] refers to a field in a document. @@ -91,7 +84,7 @@ abstract class QueryPlatform { final ListEquality equality = const ListEquality(); final List> conditions = - List>.from(_parameters['where']); + List>.from(parameters['where']); void addCondition(dynamic field, String operator, dynamic value) { final List condition = [field, operator, value]; @@ -123,7 +116,7 @@ abstract class QueryPlatform { addCondition(field, '==', null); } - return _copyWithParameters({'where': conditions}); + return copyWithParameters({'where': conditions}); } /// Creates and returns a new [Query] that's additionally sorted by the specified @@ -142,7 +135,7 @@ abstract class QueryPlatform { 'Supported [field] types are [String] and [FieldPath].'); final List> orders = - List>.from(_parameters['orderBy']); + List>.from(parameters['orderBy']); final List order = [field, descending]; assert(orders.where((List item) => field == item[0]).isEmpty, @@ -150,10 +143,10 @@ abstract class QueryPlatform { assert(() { if (field == FieldPath.documentId) { - return !(_parameters.containsKey('startAfterDocument') || - _parameters.containsKey('startAtDocument') || - _parameters.containsKey('endAfterDocument') || - _parameters.containsKey('endAtDocument')); + return !(parameters.containsKey('startAfterDocument') || + parameters.containsKey('startAtDocument') || + parameters.containsKey('endAfterDocument') || + parameters.containsKey('endAtDocument')); } return true; }(), @@ -161,7 +154,7 @@ abstract class QueryPlatform { 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); orders.add(order); - return _copyWithParameters({'orderBy': orders}); + return copyWithParameters({'orderBy': orders}); } /// Creates and returns a new [Query] that starts after the provided document @@ -180,17 +173,17 @@ abstract class QueryPlatform { /// * [endAtDocument] for a query that ends at a document. Query startAfterDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); assert( - List>.from(_parameters['orderBy']) + List>.from(parameters['orderBy']) .where((List item) => item[0] == FieldPath.documentId) .isEmpty, '[startAfterDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'startAfterDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -215,17 +208,17 @@ abstract class QueryPlatform { /// * [endBeforeDocument] for a query that ends before a document. Query startAtDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); assert( - List>.from(_parameters['orderBy']) + List>.from(parameters['orderBy']) .where((List item) => item[0] == FieldPath.documentId) .isEmpty, '[startAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'startAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -244,11 +237,11 @@ abstract class QueryPlatform { /// [endBefore], [endAtDocument] and [endBeforeDocument]. Query startAfter(List values) { assert(values != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAfter': values}); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + return copyWithParameters({'startAfter': values}); } /// Takes a list of [values], creates and returns a new [Query] that starts at @@ -261,11 +254,11 @@ abstract class QueryPlatform { /// [endBefore], [endAtDocument] and [endBeforeDocument]. Query startAt(List values) { assert(values != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAt': values}); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + return copyWithParameters({'startAt': values}); } /// Creates and returns a new [Query] that ends at the provided document @@ -284,17 +277,17 @@ abstract class QueryPlatform { /// * [endBeforeDocument] for a query that ends before a document. Query endAtDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); assert( - List>.from(_parameters['orderBy']) + List>.from(parameters['orderBy']) .where((List item) => item[0] == FieldPath.documentId) .isEmpty, '[endAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'endAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -313,11 +306,11 @@ abstract class QueryPlatform { /// [startAfter], [startAtDocument] and [startAfterDocument]. Query endAt(List values) { assert(values != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endAt': values}); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + return copyWithParameters({'endAt': values}); } /// Creates and returns a new [Query] that ends before the provided document @@ -336,17 +329,17 @@ abstract class QueryPlatform { /// * [endAtDocument] for a query that ends at a document. Query endBeforeDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); assert( - List>.from(_parameters['orderBy']) + List>.from(parameters['orderBy']) .where((List item) => item[0] == FieldPath.documentId) .isEmpty, '[endBeforeDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'endBeforeDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -365,17 +358,17 @@ abstract class QueryPlatform { /// [startAfter], [startAtDocument] and [startAfterDocument]. Query endBefore(List values) { assert(values != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endBefore': values}); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + return copyWithParameters({'endBefore': values}); } /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. Query limit(int length) { - assert(!_parameters.containsKey('limit')); - return _copyWithParameters({'limit': length}); + assert(!parameters.containsKey('limit')); + return copyWithParameters({'limit': length}); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart index df6ccf7567e0..d87832c048f4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart @@ -6,7 +6,7 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - QuerySnapshot._(Map data, FirestorePlatform firestore) + QuerySnapshot(Map data, FirestorePlatform firestore) : documents = List.generate(data['documents'].length, (int index) { return DocumentSnapshot( diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 0b262e49fbbc..09032eb954bb 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -4,21 +4,21 @@ import 'package:firebase/firestore.dart' as web; class CollectionReferenceWeb extends CollectionReference { final web.Firestore webFirestore; - final List _pathComponents; + final List pathComponents; CollectionReferenceWeb( - this.webFirestore, FirestorePlatform firestore, this._pathComponents) - : super(firestore, _pathComponents); + this.webFirestore, FirestorePlatform firestore, this.pathComponents) + : super(firestore, pathComponents); @override DocumentReference parent() { - if (_pathComponents.length < 2) { + if (pathComponents.length < 2) { return null; } return DocumentReferenceWeb( webFirestore, firestore, - (List.from(_pathComponents)..removeLast()), + (List.from(pathComponents)..removeLast()), ); } @@ -27,9 +27,9 @@ class CollectionReferenceWeb extends CollectionReference { List childPath; if (path == null) { final String key = AutoIdGenerator.autoId(); - childPath = List.from(_pathComponents)..add(key); + childPath = List.from(pathComponents)..add(key); } else { - childPath = List.from(_pathComponents)..addAll(path.split(('/'))); + childPath = List.from(pathComponents)..addAll(path.split(('/'))); } return DocumentReferenceWeb( webFirestore, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 7c27466fca76..1f6177413f0e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -1,6 +1,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/collection_reference_web.dart'; import 'package:cloud_firestore_web/document_reference_web.dart'; +import 'package:cloud_firestore_web/query_web.dart'; import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Settings; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; @@ -19,7 +20,7 @@ class FirestoreWeb extends FirestorePlatform { CollectionReferenceWeb(app, this, path.split('/')); @override - Query collectionGroup(String path) => Query( + Query collectionGroup(String path) => QueryWeb(app, firestore: this, isCollectionGroup: true, pathComponents: path.split('/')); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart new file mode 100644 index 000000000000..178ca16aceb1 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -0,0 +1,47 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +class QueryWeb extends Query { + final web.Firestore webFirestore; + QueryWeb( + this.webFirestore, + {FirestorePlatform firestore, + List pathComponents, + bool isCollectionGroup = false, + Map parameters}) + : super( + firestore: firestore, + pathComponents: pathComponents, + isCollectionGroup: isCollectionGroup, + parameters: parameters); + + @override + Query copyWithParameters(Map parameters) { + return QueryWeb( + webFirestore, + firestore: firestore, + isCollectionGroup: isCollectionGroup, + pathComponents: pathComponents, + parameters: Map.unmodifiable( + Map.from(parameters)..addAll(parameters), + ), + ); + } + + @override + Stream snapshots({bool includeMetadataChanges = false}) { +// Future _handle; +// // It's fine to let the StreamController be garbage collected once all the +// // subscribers have cancelled; this analyzer warning is safe to ignore. +// StreamController controller; // ignore: close_sinks + + } + + @override + Future getDocuments({Source source = Source.serverAndCache}) async { + } + + QuerySnapshot _fromWeb(web.QuerySnapshot webSnapshot) { + + } +} From 14bad9cf961b85e651792c1095ae4b9872dcc9ac Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 09:20:24 +0000 Subject: [PATCH 004/144] created base QuerySnapshot --- .../cloud_firestore_platform_interface.dart | 1 + .../lib/src/method_channel_firestore.dart | 2 +- .../src/method_channel_query_snapshot.dart | 35 +++++++++++++++++++ .../lib/src/query.dart | 2 +- .../lib/src/query_snapshot.dart | 27 ++------------ 5 files changed, 40 insertions(+), 27 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index b9757441008c..3d0fa4f6de54 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -43,6 +43,7 @@ part 'src/query.dart'; part 'src/query_interface.dart'; part 'src/query_snapshot.dart'; +part 'src/method_channel_query_snapshot.dart'; part 'src/snapshot_metadata.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index b74d3a2a8694..4feef504c835 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -15,7 +15,7 @@ class MethodChannelFirestore extends FirestorePlatform { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { - final QuerySnapshot snapshot = QuerySnapshot(call.arguments, this); + final QuerySnapshot snapshot = MethodChannelQuerySnapshot(call.arguments, this); _queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { final DocumentSnapshot snapshot = DocumentSnapshot( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart new file mode 100644 index 000000000000..0f6feaaba206 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart @@ -0,0 +1,35 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A QuerySnapshot contains zero or more DocumentSnapshot objects. +class MethodChannelQuerySnapshot extends QuerySnapshot { + MethodChannelQuerySnapshot( + Map data, FirestorePlatform firestore) + : super( + List.generate(data['documents'].length, + (int index) { + return DocumentSnapshot( + data['paths'][index], + _asStringKeyedMap(data['documents'][index]), + SnapshotMetadata( + data['metadatas'][index]['hasPendingWrites'], + data['metadatas'][index]['isFromCache'], + ), + firestore, + ); + }), + List.generate(data['documentChanges'].length, + (int index) { + return DocumentChange._( + data['documentChanges'][index], + firestore, + ); + }), + SnapshotMetadata( + data['metadata']['hasPendingWrites'], + data['metadata']['isFromCache'], + )); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart index c128f1ea0545..382b41cdd33e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart @@ -77,6 +77,6 @@ class QueryPlatform extends Query{ 'source': _getSourceString(source), }, ); - return QuerySnapshot(data, firestore); + return MethodChannelQuerySnapshot(data, firestore); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart index d87832c048f4..5be5ccf59b99 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart @@ -6,31 +6,8 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - QuerySnapshot(Map data, FirestorePlatform firestore) - : documents = List.generate(data['documents'].length, - (int index) { - return DocumentSnapshot( - data['paths'][index], - _asStringKeyedMap(data['documents'][index]), - SnapshotMetadata( - data['metadatas'][index]['hasPendingWrites'], - data['metadatas'][index]['isFromCache'], - ), - firestore, - ); - }), - documentChanges = List.generate( - data['documentChanges'].length, (int index) { - return DocumentChange._( - data['documentChanges'][index], - firestore, - ); - }), - metadata = SnapshotMetadata( - data['metadata']['hasPendingWrites'], - data['metadata']['isFromCache'], - ); - + + QuerySnapshot(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot final List documents; From 552305de61e99a490eea8ad917bbb86b81a0864a Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 09:35:33 +0000 Subject: [PATCH 005/144] organised platform_interface module --- .../lib/cloud_firestore_platform_interface.dart | 12 ++++++------ .../lib/src/method_channel_collection_reference.dart | 2 +- ...e.dart => method_channel_document_reference.dart} | 0 .../lib/src/method_channel_firestore.dart | 6 +++--- .../src/{query.dart => method_channel_query.dart} | 6 +++--- .../collection_reference.dart | 2 +- .../document_reference_interface.dart | 8 ++++---- .../query.dart} | 2 +- .../src/{ => platform_interface}/query_snapshot.dart | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{document_reference.dart => method_channel_document_reference.dart} (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{query.dart => method_channel_query.dart} (96%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/collection_reference.dart (97%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/document_reference_interface.dart (93%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{query_interface.dart => platform_interface/query.dart} (99%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/query_snapshot.dart (96%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 3d0fa4f6de54..698741038a3d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -19,14 +19,14 @@ part 'src/blob.dart'; part 'src/utils/auto_id_generator.dart'; -part 'src/collection_reference.dart'; +part 'src/platform_interface/collection_reference.dart'; part 'src/method_channel_collection_reference.dart'; part 'src/document_change.dart'; -part 'src/document_reference.dart'; +part 'src/method_channel_document_reference.dart'; -part 'src/document_reference_interface.dart'; +part 'src/platform_interface/document_reference_interface.dart'; part 'src/document_snapshot.dart'; @@ -38,11 +38,11 @@ part 'src/firestore_message_codec.dart'; part 'src/geo_point.dart'; -part 'src/query.dart'; +part 'src/method_channel_query.dart'; -part 'src/query_interface.dart'; +part 'src/platform_interface/query.dart'; -part 'src/query_snapshot.dart'; +part 'src/platform_interface/query_snapshot.dart'; part 'src/method_channel_query_snapshot.dart'; part 'src/snapshot_metadata.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart index 20397f785225..a04d30be9d48 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart @@ -7,7 +7,7 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [Query]). -class MethodChannelCollectionReference extends QueryPlatform implements CollectionReference { +class MethodChannelCollectionReference extends MethodChannelQuery implements CollectionReference { MethodChannelCollectionReference(FirestorePlatform firestore, List pathComponents) : super(firestore: firestore,pathComponents: pathComponents); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 4feef504c835..6ccce77b47fb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -63,14 +63,14 @@ class MethodChannelFirestore extends FirestorePlatform { @override CollectionReference collection(String path) { assert(path != null); - return CollectionReference(this, path.split('/')); + return MethodChannelCollectionReference(this, path.split('/')); } @override Query collectionGroup(String path) { assert(path != null); assert(!path.contains("/"), "Collection IDs must not contain '/'."); - return QueryPlatform( + return MethodChannelQuery( firestore: this, isCollectionGroup: true, pathComponents: path.split('/'), @@ -80,7 +80,7 @@ class MethodChannelFirestore extends FirestorePlatform { @override DocumentReference document(String path) { assert(path != null); - return DocumentReference(this, path.split('/')); + return MethodChannelDocumentReference(this, path.split('/')); } @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart similarity index 96% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index 382b41cdd33e..253a5e9e1705 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -5,8 +5,8 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -class QueryPlatform extends Query{ - QueryPlatform( +class MethodChannelQuery extends Query{ + MethodChannelQuery( {@required FirestorePlatform firestore, @required List pathComponents, bool isCollectionGroup = false, @@ -15,7 +15,7 @@ class QueryPlatform extends Query{ Query copyWithParameters(Map parameters) { - return QueryPlatform( + return MethodChannelQuery( firestore: firestore, isCollectionGroup: isCollectionGroup, pathComponents: pathComponents, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart similarity index 97% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index 7f8ff592c62a..012cf8a16433 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -7,7 +7,7 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [Query]). -class CollectionReference extends Query { +abstract class CollectionReference extends Query { CollectionReference(FirestorePlatform firestore, List pathComponents) : super(firestore: firestore, pathComponents: pathComponents); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart similarity index 93% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart index 1c6a9f85cf33..77fd723cbd15 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_reference_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart @@ -6,7 +6,7 @@ part of cloud_firestore_platform_interface; /// The document at the referenced location may or may not exist. /// A [DocumentReference] can also be used to create a [CollectionReference] /// to a subcollection. -class DocumentReference { +abstract class DocumentReference { DocumentReference(this.firestore, this._pathComponents); /// The Firestore instance associated with this document reference @@ -22,9 +22,9 @@ class DocumentReference { /// Parent returns the containing [CollectionReference]. CollectionReference parent() { - return CollectionReference( - firestore, - (List.from(_pathComponents)..removeLast()), + final parentPathComponents = List.from(_pathComponents)..removeLast(); + return firestore.collection( + parentPathComponents.join("/"), ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart similarity index 99% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 1468c1dcdcb1..2e6f8dd022f0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -54,7 +54,7 @@ abstract class Query { /// Obtains a CollectionReference corresponding to this query's location. CollectionReference reference() => - CollectionReference(firestore, pathComponents); + firestore.collection(pathComponents.join("/")); /// Creates and returns a new [Query] with additional filter on specified /// [field]. [field] refers to a field in a document. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart similarity index 96% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 5be5ccf59b99..a889617daaf6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -5,7 +5,7 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. -class QuerySnapshot { +abstract class QuerySnapshot { QuerySnapshot(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot From 63f3488584b7a2c909c47d230dc50d6883c9dd6e Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 11:04:17 +0000 Subject: [PATCH 006/144] - created query_web - added where support --- .../cloud_firestore_platform_interface.dart | 3 +- .../src/method_channel_document_change.dart | 26 ++ .../document_change.dart | 14 +- .../platform_interface/query_snapshot.dart | 2 +- .../lib/firestore_web.dart | 7 +- .../cloud_firestore_web/lib/query_web.dart | 261 +++++++++++++++--- 6 files changed, 257 insertions(+), 56 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/document_change.dart (74%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 698741038a3d..0e02babae9d6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -22,7 +22,8 @@ part 'src/utils/auto_id_generator.dart'; part 'src/platform_interface/collection_reference.dart'; part 'src/method_channel_collection_reference.dart'; -part 'src/document_change.dart'; +part 'src/method_channel_document_change.dart'; +part 'src/platform_interface/document_change.dart'; part 'src/method_channel_document_reference.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart new file mode 100644 index 000000000000..c50c63aedbaf --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart @@ -0,0 +1,26 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// A DocumentChange represents a change to the documents matching a query. +/// +/// It contains the document affected and the type of change that occurred +/// (added, modified, or removed). +class MethodChannelDocumentChange extends DocumentChange { + MethodChannelDocumentChange._( + Map data, FirestorePlatform firestore) + : super(DocumentChangeType.values.firstWhere((DocumentChangeType type) { + return type.toString() == data['type']; + }), + data['oldIndex'], + data['newIndex'], + DocumentSnapshot( + data['path'], + _asStringKeyedMap(data['document']), + SnapshotMetadata(data["metadata"]["hasPendingWrites"], + data["metadata"]["isFromCache"]), + firestore, + )); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart similarity index 74% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 253e10c0d525..5a7bd4bf750b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -23,19 +23,7 @@ enum DocumentChangeType { /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class DocumentChange { - DocumentChange._(Map data, FirestorePlatform firestore) - : oldIndex = data['oldIndex'], - newIndex = data['newIndex'], - document = DocumentSnapshot( - data['path'], - _asStringKeyedMap(data['document']), - SnapshotMetadata(data["metadata"]["hasPendingWrites"], - data["metadata"]["isFromCache"]), - firestore, - ), - type = DocumentChangeType.values.firstWhere((DocumentChangeType type) { - return type.toString() == data['type']; - }); + DocumentChange(this.type, this.oldIndex, this.newIndex, this.document); /// The type of change that occurred (added, modified, or removed). final DocumentChangeType type; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index a889617daaf6..5be5ccf59b99 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -5,7 +5,7 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. -abstract class QuerySnapshot { +class QuerySnapshot { QuerySnapshot(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 1f6177413f0e..c0f7f1f6f28e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -20,10 +20,9 @@ class FirestoreWeb extends FirestorePlatform { CollectionReferenceWeb(app, this, path.split('/')); @override - Query collectionGroup(String path) => QueryWeb(app, - firestore: this, - isCollectionGroup: true, - pathComponents: path.split('/')); + Query collectionGroup(String path) { + app.collectionGroup(path); + } @override DocumentReference document(String path) => diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 178ca16aceb1..930844c5002e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,47 +1,234 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -class QueryWeb extends Query { - final web.Firestore webFirestore; - QueryWeb( - this.webFirestore, - {FirestorePlatform firestore, - List pathComponents, - bool isCollectionGroup = false, - Map parameters}) - : super( - firestore: firestore, - pathComponents: pathComponents, - isCollectionGroup: isCollectionGroup, - parameters: parameters); - - @override - Query copyWithParameters(Map parameters) { - return QueryWeb( - webFirestore, - firestore: firestore, - isCollectionGroup: isCollectionGroup, - pathComponents: pathComponents, - parameters: Map.unmodifiable( - Map.from(parameters)..addAll(parameters), - ), - ); - } - +class QueryWeb implements Query { + final web.CollectionReference webCollection; + final web.Query webQuery; + final FirestorePlatform _firestore; + final bool _isCollectionGroup; + final String _path; + + QueryWeb(this._firestore,this._path, {bool isCollectionGroup, this.webCollection, this.webQuery}): this._isCollectionGroup = isCollectionGroup ?? false; + @override Stream snapshots({bool includeMetadataChanges = false}) { -// Future _handle; -// // It's fine to let the StreamController be garbage collected once all the -// // subscribers have cancelled; this analyzer warning is safe to ignore. -// StreamController controller; // ignore: close_sinks - + assert(webQuery != null || webCollection != null); + Stream webSnapshots; + if (webQuery != null) { + webSnapshots = webQuery.onSnapshot; + } else if (webCollection != null) { + webSnapshots = webCollection.onSnapshot; + } + return webSnapshots.map(_webQuerySnapshotToQuerySnapshot); } - + @override - Future getDocuments({Source source = Source.serverAndCache}) async { + Future getDocuments( + {Source source = Source.serverAndCache}) async { + assert(webQuery != null || webCollection != null); + web.QuerySnapshot webDocuments; + if (webQuery != null) { + webDocuments = await webQuery.get(); + } else if (webCollection != null) { + webDocuments = await webCollection.get(); + } + + return _webQuerySnapshotToQuerySnapshot(webDocuments); } - - QuerySnapshot _fromWeb(web.QuerySnapshot webSnapshot) { - + + @override + Map buildArguments() { + return null; + } + + @override + Query endAt(List values) => QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.endAt(fieldValues: values), + webCollection: webCollection ?? webCollection.endAt(fieldValues: values) + ); + + @override + Query endAtDocument(DocumentSnapshot documentSnapshot) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.endAt(snapshot: ), + webCollection: webCollection ?? webCollection.endAt(snapshot: ) + ); + + @override + Query endBefore(List values) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.endBefore(fieldValues: values), + webCollection: webCollection ?? webCollection.endBefore(fieldValues: values) + ); + + @override + Query endBeforeDocument(DocumentSnapshot documentSnapshot) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.endAt(), + webCollection: webCollection ?? webCollection.endAt() + ); + + @override + FirestorePlatform get firestore => _firestore; + + @override + bool get isCollectionGroup => _isCollectionGroup; + + @override + Query limit(int length) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.limit(length), + webCollection: webCollection ?? webCollection.limit(length) + ); + + @override + Query orderBy(field, {bool descending = false}) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.orderBy(field, descending ? "desc" : "asc"), + webCollection: webCollection ?? webCollection.orderBy(field, descending ? "desc" : "asc"), + ); + + @override + Map get parameters => null; + + @override + String get path => this._path; + + @override + // TODO: implement pathComponents + List get pathComponents => this._path.split("/"); + + @override + CollectionReference reference() => firestore.collection(_path); + + @override + Query startAfter(List values) => QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.startAfter(fieldValues: values), + webCollection: webCollection ?? webCollection.startAfter(fieldValues: values), + ); + + @override + Query startAfterDocument(DocumentSnapshot documentSnapshot) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.startAfter(snapshot: ), + webCollection: webCollection ?? webCollection.startAfter(snapshot: ), + ); + + @override + Query startAt(List values) => QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.startAt(fieldValues: values), + webCollection: webCollection ?? webCollection.startAt(fieldValues: values), + ); + + @override + Query startAtDocument(DocumentSnapshot documentSnapshot) => + QueryWeb( + this._firestore, + this._path, + webQuery: webQuery ?? webQuery.startAt(snapshot: ), + webCollection: webCollection ?? webCollection.startAt(snapshot: ), + ); + + @override + Query where(field, + {isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull}) { + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + assert(webQuery != null || webCollection != null); + web.Query query; + if (webQuery != null) { + query = webQuery; + } else if (webCollection != null) { + query = webCollection; + } + if(isEqualTo != null) { + query = query.where(field, "==", isEqualTo); + } + if(isLessThan != null) { + query = query.where(field, "<", isLessThan); + } + if(isLessThanOrEqualTo != null) { + query = query.where(field, "<=", isLessThanOrEqualTo); + } + if(isGreaterThan != null) { + query = query.where(field, ">", isGreaterThan); + } + if(isGreaterThanOrEqualTo != null) { + query = query.where(field, ">=", isGreaterThanOrEqualTo); + } + if(arrayContains != null) { + query = query.where(field, "array-contains", arrayContains); + } + if(arrayContainsAny != null) { + assert(arrayContainsAny.length <= 10, "array contains can have maximum of 10 items"); + query = query.where(field, "array-contains-any", arrayContainsAny); + } + if(whereIn != null) { + assert(whereIn.length <= 10, "array contains can have maximum of 10 items"); + query = query.where(field, "in", whereIn); + } + if(isNull != null ) { + assert( + isNull, + 'isNull can only be set to true. ' + 'Use isEqualTo to filter on non-null values.'); + query = query.where(field, "==", null); + } } + + @override + Query copyWithParameters(Map parameters) => this; + + QuerySnapshot _webQuerySnapshotToQuerySnapshot(web.QuerySnapshot webSnapshot) => + QuerySnapshot( + webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot), + webSnapshot.docChanges().map(_webChangeToChange), + _webMetadataToMetada(webSnapshot.metadata)); + + DocumentChange _webChangeToChange(web.DocumentChange webChange) => + DocumentChange( + DocumentChangeType.values.firstWhere((DocumentChangeType type) { + return type.toString() == webChange.type.toLowerCase(); + }), webChange.oldIndex, webChange.newIndex, + _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); + + DocumentSnapshot _webDocumentSnapshotToDocumentSnapshot(web.DocumentSnapshot webSnapshot) => + DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata(webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache), + this._firestore); + + SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) => + SnapshotMetadata( + webMetadata.hasPendingWrites, + webMetadata.fromCache + ); } From 9c7ea4af370330303bbdeeacff6fcaa62472357f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 11:05:02 +0000 Subject: [PATCH 007/144] - fixed method_channel_query_snapshot --- .../lib/src/method_channel_query_snapshot.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart index 0f6feaaba206..f0b515420dc6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart @@ -23,7 +23,7 @@ class MethodChannelQuerySnapshot extends QuerySnapshot { }), List.generate(data['documentChanges'].length, (int index) { - return DocumentChange._( + return MethodChannelDocumentChange._( data['documentChanges'][index], firestore, ); From 250f0172b2df81336e86caba3c9ad2b98d12581e Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 11:27:25 +0000 Subject: [PATCH 008/144] - implemented query_web --- .../lib/src/method_channel_query.dart | 2 +- .../lib/src/platform_interface/query.dart | 24 +-- .../cloud_firestore_web/lib/query_web.dart | 157 +++++++++--------- 3 files changed, 88 insertions(+), 95 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index 253a5e9e1705..7b320448e8e9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -14,7 +14,7 @@ class MethodChannelQuery extends Query{ :super(firestore: firestore, pathComponents: pathComponents, isCollectionGroup: isCollectionGroup, parameters: parameters); - Query copyWithParameters(Map parameters) { + Query _copyWithParameters(Map parameters) { return MethodChannelQuery( firestore: firestore, isCollectionGroup: isCollectionGroup, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 2e6f8dd022f0..22055c5ee1a6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -30,7 +30,7 @@ abstract class Query { String get path => pathComponents.join('/'); - Query copyWithParameters(Map parameters) { + Query _copyWithParameters(Map parameters) { throw UnimplementedError("copyWithParameters() is not implemented"); } @@ -116,7 +116,7 @@ abstract class Query { addCondition(field, '==', null); } - return copyWithParameters({'where': conditions}); + return _copyWithParameters({'where': conditions}); } /// Creates and returns a new [Query] that's additionally sorted by the specified @@ -154,7 +154,7 @@ abstract class Query { 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); orders.add(order); - return copyWithParameters({'orderBy': orders}); + return _copyWithParameters({'orderBy': orders}); } /// Creates and returns a new [Query] that starts after the provided document @@ -183,7 +183,7 @@ abstract class Query { .isEmpty, '[startAfterDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); - return copyWithParameters({ + return _copyWithParameters({ 'startAfterDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -218,7 +218,7 @@ abstract class Query { .isEmpty, '[startAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); - return copyWithParameters({ + return _copyWithParameters({ 'startAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -241,7 +241,7 @@ abstract class Query { assert(!parameters.containsKey('startAt')); assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); - return copyWithParameters({'startAfter': values}); + return _copyWithParameters({'startAfter': values}); } /// Takes a list of [values], creates and returns a new [Query] that starts at @@ -258,7 +258,7 @@ abstract class Query { assert(!parameters.containsKey('startAt')); assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); - return copyWithParameters({'startAt': values}); + return _copyWithParameters({'startAt': values}); } /// Creates and returns a new [Query] that ends at the provided document @@ -287,7 +287,7 @@ abstract class Query { .isEmpty, '[endAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); - return copyWithParameters({ + return _copyWithParameters({ 'endAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -310,7 +310,7 @@ abstract class Query { assert(!parameters.containsKey('endAt')); assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); - return copyWithParameters({'endAt': values}); + return _copyWithParameters({'endAt': values}); } /// Creates and returns a new [Query] that ends before the provided document @@ -339,7 +339,7 @@ abstract class Query { .isEmpty, '[endBeforeDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); - return copyWithParameters({ + return _copyWithParameters({ 'endBeforeDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -362,13 +362,13 @@ abstract class Query { assert(!parameters.containsKey('endAt')); assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); - return copyWithParameters({'endBefore': values}); + return _copyWithParameters({'endBefore': values}); } /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. Query limit(int length) { assert(!parameters.containsKey('limit')); - return copyWithParameters({'limit': length}); + return _copyWithParameters({'limit': length}); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 930844c5002e..dd43714ff828 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -8,7 +8,9 @@ class QueryWeb implements Query { final bool _isCollectionGroup; final String _path; - QueryWeb(this._firestore,this._path, {bool isCollectionGroup, this.webCollection, this.webQuery}): this._isCollectionGroup = isCollectionGroup ?? false; + QueryWeb(this._firestore, this._path, + {bool isCollectionGroup, this.webCollection, this.webQuery}) + : this._isCollectionGroup = isCollectionGroup ?? false; @override Stream snapshots({bool includeMetadataChanges = false}) { @@ -42,39 +44,27 @@ class QueryWeb implements Query { } @override - Query endAt(List values) => QueryWeb( - this._firestore, - this._path, + Query endAt(List values) => QueryWeb(this._firestore, this._path, webQuery: webQuery ?? webQuery.endAt(fieldValues: values), - webCollection: webCollection ?? webCollection.endAt(fieldValues: values) - ); + webCollection: webCollection ?? webCollection.endAt(fieldValues: values)); @override Query endAtDocument(DocumentSnapshot documentSnapshot) => - QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.endAt(snapshot: ), - webCollection: webCollection ?? webCollection.endAt(snapshot: ) - ); + QueryWeb(this._firestore, this._path, + webQuery: _generateOrderByQuery(documentSnapshot) + .endAt(fieldValues: documentSnapshot.data.values)); @override - Query endBefore(List values) => - QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.endBefore(fieldValues: values), - webCollection: webCollection ?? webCollection.endBefore(fieldValues: values) - ); + Query endBefore(List values) => QueryWeb(this._firestore, this._path, + webQuery: webQuery ?? webQuery.endBefore(fieldValues: values), + webCollection: + webCollection ?? webCollection.endBefore(fieldValues: values)); @override Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.endAt(), - webCollection: webCollection ?? webCollection.endAt() - ); + QueryWeb(this._firestore, this._path, + webQuery: _generateOrderByQuery(documentSnapshot) + .endBefore(fieldValues: documentSnapshot.data.values)); @override FirestorePlatform get firestore => _firestore; @@ -83,21 +73,18 @@ class QueryWeb implements Query { bool get isCollectionGroup => _isCollectionGroup; @override - Query limit(int length) => - QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.limit(length), - webCollection: webCollection ?? webCollection.limit(length) - ); + Query limit(int length) => QueryWeb(this._firestore, this._path, + webQuery: webQuery ?? webQuery.limit(length), + webCollection: webCollection ?? webCollection.limit(length)); @override - Query orderBy(field, {bool descending = false}) => - QueryWeb( - this._firestore, + Query orderBy(field, {bool descending = false}) => QueryWeb( + this._firestore, this._path, - webQuery: webQuery ?? webQuery.orderBy(field, descending ? "desc" : "asc"), - webCollection: webCollection ?? webCollection.orderBy(field, descending ? "desc" : "asc"), + webQuery: + webQuery ?? webQuery.orderBy(field, descending ? "desc" : "asc"), + webCollection: webCollection ?? + webCollection.orderBy(field, descending ? "desc" : "asc"), ); @override @@ -107,7 +94,6 @@ class QueryWeb implements Query { String get path => this._path; @override - // TODO: implement pathComponents List get pathComponents => this._path.split("/"); @override @@ -115,38 +101,34 @@ class QueryWeb implements Query { @override Query startAfter(List values) => QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.startAfter(fieldValues: values), - webCollection: webCollection ?? webCollection.startAfter(fieldValues: values), - ); - - @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) => - QueryWeb( this._firestore, this._path, - webQuery: webQuery ?? webQuery.startAfter(snapshot: ), - webCollection: webCollection ?? webCollection.startAfter(snapshot: ), + webQuery: webQuery ?? webQuery.startAfter(fieldValues: values), + webCollection: + webCollection ?? webCollection.startAfter(fieldValues: values), ); @override - Query startAt(List values) => QueryWeb( - this._firestore, - this._path, - webQuery: webQuery ?? webQuery.startAt(fieldValues: values), - webCollection: webCollection ?? webCollection.startAt(fieldValues: values), - ); + Query startAfterDocument(DocumentSnapshot documentSnapshot) => + QueryWeb(this._firestore, this._path, + webQuery: _generateOrderByQuery(documentSnapshot) + .startAfter(fieldValues: documentSnapshot.data.values)); @override - Query startAtDocument(DocumentSnapshot documentSnapshot) => - QueryWeb( + Query startAt(List values) => QueryWeb( this._firestore, this._path, - webQuery: webQuery ?? webQuery.startAt(snapshot: ), - webCollection: webCollection ?? webCollection.startAt(snapshot: ), + webQuery: webQuery ?? webQuery.startAt(fieldValues: values), + webCollection: + webCollection ?? webCollection.startAt(fieldValues: values), ); + @override + Query startAtDocument(DocumentSnapshot documentSnapshot) => + QueryWeb(this._firestore, this._path, + webQuery: _generateOrderByQuery(documentSnapshot) + .startAt(fieldValues: documentSnapshot.data.values)); + @override Query where(field, {isEqualTo, @@ -159,7 +141,7 @@ class QueryWeb implements Query { List whereIn, bool isNull}) { assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); + 'Supported [field] types are [String] and [FieldPath].'); assert(webQuery != null || webCollection != null); web.Query query; if (webQuery != null) { @@ -167,45 +149,46 @@ class QueryWeb implements Query { } else if (webCollection != null) { query = webCollection; } - if(isEqualTo != null) { + if (isEqualTo != null) { query = query.where(field, "==", isEqualTo); } - if(isLessThan != null) { + if (isLessThan != null) { query = query.where(field, "<", isLessThan); } - if(isLessThanOrEqualTo != null) { + if (isLessThanOrEqualTo != null) { query = query.where(field, "<=", isLessThanOrEqualTo); } - if(isGreaterThan != null) { + if (isGreaterThan != null) { query = query.where(field, ">", isGreaterThan); } - if(isGreaterThanOrEqualTo != null) { + if (isGreaterThanOrEqualTo != null) { query = query.where(field, ">=", isGreaterThanOrEqualTo); } - if(arrayContains != null) { + if (arrayContains != null) { query = query.where(field, "array-contains", arrayContains); } - if(arrayContainsAny != null) { - assert(arrayContainsAny.length <= 10, "array contains can have maximum of 10 items"); + if (arrayContainsAny != null) { + assert(arrayContainsAny.length <= 10, + "array contains can have maximum of 10 items"); query = query.where(field, "array-contains-any", arrayContainsAny); } - if(whereIn != null) { - assert(whereIn.length <= 10, "array contains can have maximum of 10 items"); + if (whereIn != null) { + assert( + whereIn.length <= 10, "array contains can have maximum of 10 items"); query = query.where(field, "in", whereIn); } - if(isNull != null ) { + if (isNull != null) { assert( - isNull, - 'isNull can only be set to true. ' + isNull, + 'isNull can only be set to true. ' 'Use isEqualTo to filter on non-null values.'); query = query.where(field, "==", null); } + return QueryWeb(this._firestore, this._path, webQuery: query); } - @override - Query copyWithParameters(Map parameters) => this; - - QuerySnapshot _webQuerySnapshotToQuerySnapshot(web.QuerySnapshot webSnapshot) => + QuerySnapshot _webQuerySnapshotToQuerySnapshot( + web.QuerySnapshot webSnapshot) => QuerySnapshot( webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot), webSnapshot.docChanges().map(_webChangeToChange), @@ -218,7 +201,8 @@ class QueryWeb implements Query { }), webChange.oldIndex, webChange.newIndex, _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); - DocumentSnapshot _webDocumentSnapshotToDocumentSnapshot(web.DocumentSnapshot webSnapshot) => + DocumentSnapshot _webDocumentSnapshotToDocumentSnapshot( + web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, webSnapshot.data(), @@ -226,9 +210,18 @@ class QueryWeb implements Query { webSnapshot.metadata.fromCache), this._firestore); + web.Query _generateOrderByQuery(DocumentSnapshot webSnapshot) { + assert(webQuery != null || webCollection != null); + web.Query query; + if (webQuery != null) { + query = webQuery; + } else if (webCollection != null) { + query = webCollection; + } + webSnapshot.data.keys.forEach((key) => query = query.orderBy(key)); + return query.endAt(fieldValues: webSnapshot.data.values); + } + SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) => - SnapshotMetadata( - webMetadata.hasPendingWrites, - webMetadata.fromCache - ); + SnapshotMetadata(webMetadata.hasPendingWrites, webMetadata.fromCache); } From dfaa02a44b55b9f55d386374dc903eed3eda2a24 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 12:11:36 +0000 Subject: [PATCH 009/144] - delegated collection_reference_web to use query_web --- .../lib/collection_reference_web.dart | 96 ++++++++++++++++++- .../lib/firestore_web.dart | 9 +- 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 09032eb954bb..2eb63481eb65 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -1,14 +1,18 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/document_reference_web.dart'; +import 'package:cloud_firestore_web/query_web.dart'; import 'package:firebase/firestore.dart' as web; -class CollectionReferenceWeb extends CollectionReference { +class CollectionReferenceWeb implements CollectionReference { final web.Firestore webFirestore; + final FirestorePlatform _firestorePlatform; final List pathComponents; + final QueryWeb queryDelegate; CollectionReferenceWeb( - this.webFirestore, FirestorePlatform firestore, this.pathComponents) - : super(firestore, pathComponents); + this._firestorePlatform, this.webFirestore, this.pathComponents) + : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), + webCollection: webFirestore.collection(pathComponents.join("/"))); @override DocumentReference parent() { @@ -44,4 +48,90 @@ class CollectionReferenceWeb extends CollectionReference { await newDocument.setData(data); return newDocument; } + + @override + Map buildArguments() => queryDelegate.buildArguments(); + + @override + Query endAt(List values) => queryDelegate.endAt(values); + + @override + Query endAtDocument(DocumentSnapshot documentSnapshot) => + queryDelegate.endAtDocument(documentSnapshot); + + @override + Query endBefore(List values) => queryDelegate.endBefore(values); + + @override + Query endBeforeDocument(DocumentSnapshot documentSnapshot) => + queryDelegate.endBeforeDocument(documentSnapshot); + + @override + FirestorePlatform get firestore => _firestorePlatform; + + @override + Future getDocuments({Source source = Source.serverAndCache}) => + queryDelegate.getDocuments(source: source); + + @override + String get id => pathComponents.isEmpty ? null : pathComponents.last; + + @override + bool get isCollectionGroup => false; + + @override + Query limit(int length) => queryDelegate.limit(length); + + @override + Query orderBy(field, {bool descending = false}) => + queryDelegate.orderBy(field, descending: descending); + + @override + Map get parameters => queryDelegate.parameters; + + @override + String get path => pathComponents.join("/"); + + @override + CollectionReference reference() => queryDelegate.reference(); + + @override + Stream snapshots({bool includeMetadataChanges = false}) => + queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); + + @override + Query startAfter(List values) => queryDelegate.startAfter(values); + + @override + Query startAfterDocument(DocumentSnapshot documentSnapshot) => + queryDelegate.startAfterDocument(documentSnapshot); + + @override + Query startAt(List values) => queryDelegate.startAt(values); + + @override + Query startAtDocument(DocumentSnapshot documentSnapshot) => + queryDelegate.startAtDocument(documentSnapshot); + + @override + Query where(field, + {isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull}) => + queryDelegate.where(field, + isEqualTo: isEqualTo, + isLessThan: isLessThan, + isLessThanOrEqualTo: isLessThanOrEqualTo, + isGreaterThan: isGreaterThan, + isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, + arrayContains: arrayContains, + arrayContainsAny: arrayContainsAny, + whereIn: whereIn, + isNull: isNull); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index c0f7f1f6f28e..a6d74da6e750 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -17,11 +17,16 @@ class FirestoreWeb extends FirestorePlatform { @override CollectionReference collection(String path) => - CollectionReferenceWeb(app, this, path.split('/')); + CollectionReferenceWeb(this, app, path.split('/')); @override Query collectionGroup(String path) { - app.collectionGroup(path); + return QueryWeb( + this, + path, + isCollectionGroup: true, + webQuery: app.collectionGroup(path) + ); } @override From 46349f6f75a8cd92106fbae3e950f8610a673321 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 14:10:42 +0000 Subject: [PATCH 010/144] - added firestore web to firestore package --- .../cloud_firestore/lib/cloud_firestore.dart | 1 + packages/cloud_firestore/cloud_firestore/pubspec.yaml | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index aef386e77d26..0534b6a72e8a 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -16,6 +16,7 @@ import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; import 'src/utils/auto_id_generator.dart'; +export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; part 'src/blob.dart'; part 'src/collection_reference.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index 1bef85841f13..4e0019ca6f43 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -13,6 +13,8 @@ flutter: pluginClass: CloudFirestorePlugin ios: pluginClass: FLTCloudFirestorePlugin + web: + default_package: cloud_firestore_web dependencies: flutter: @@ -20,6 +22,10 @@ dependencies: meta: "^1.0.5" collection: "^1.14.3" firebase_core: "^0.4.0" + cloud_firestore_platform_interface: + path: ../cloud_firestore_platform_interface + cloud_firestore_web: + path: ../cloud_firestore_web dev_dependencies: flutter_test: From d731ecdac7d64df0307a6a71d3b701a569635e41 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 14:42:36 +0000 Subject: [PATCH 011/144] - create delegate for collection reference --- .../cloud_firestore/lib/cloud_firestore.dart | 1 + .../lib/src/collection_reference.dart | 6 +- .../cloud_firestore/lib/src/firestore.dart | 147 +++--------------- .../cloud_firestore/lib/src/write_batch.dart | 107 ++----------- .../lib/src/method_channel_firestore.dart | 1 - 5 files changed, 41 insertions(+), 221 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 0534b6a72e8a..08ab76c2713a 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -9,6 +9,7 @@ import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui' show hashValues, hashList; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index f1de3a8ba4b9..fdf7f1291baa 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -8,8 +8,12 @@ part of cloud_firestore; /// document references, and querying for documents (using the methods /// inherited from [Query]). class CollectionReference extends Query { + final platform.MethodChannelCollectionReference _delegate; + CollectionReference._(Firestore firestore, List pathComponents) - : super._(firestore: firestore, pathComponents: pathComponents); + : _delegate = platform.MethodChannelCollectionReference( + platform.FirestorePlatform.instance, pathComponents), + super._(firestore: firestore, pathComponents: pathComponents); /// ID of the referenced collection. String get id => _pathComponents.isEmpty ? null : _pathComponents.last; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 5c164ed1e122..84b61e5f7ae4 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -8,154 +8,51 @@ part of cloud_firestore; /// /// You can get an instance by calling [Firestore.instance]. class Firestore { - Firestore({FirebaseApp app}) : app = app ?? FirebaseApp.instance { - if (_initialized) return; - channel.setMethodCallHandler((MethodCall call) async { - if (call.method == 'QuerySnapshot') { - final QuerySnapshot snapshot = QuerySnapshot._(call.arguments, this); - _queryObservers[call.arguments['handle']].add(snapshot); - } else if (call.method == 'DocumentSnapshot') { - final DocumentSnapshot snapshot = DocumentSnapshot._( - call.arguments['path'], - _asStringKeyedMap(call.arguments['data']), - SnapshotMetadata._(call.arguments['metadata']['hasPendingWrites'], - call.arguments['metadata']['isFromCache']), - this, - ); - _documentObservers[call.arguments['handle']].add(snapshot); - } else if (call.method == 'DoTransaction') { - final int transactionId = call.arguments['transactionId']; - final Transaction transaction = Transaction(transactionId, this); - final dynamic result = - await _transactionHandlers[transactionId](transaction); - await transaction._finish(); - return result; - } - }); - _initialized = true; - } - - /// Gets the instance of Firestore for the default Firebase app. - static final Firestore instance = Firestore(); - /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. - /// - /// If null, the default [FirebaseApp] is used. - final FirebaseApp app; + platform.MethodChannelFirestore _platfromFirestore; - static bool _initialized = false; + Firestore({FirebaseApp app}): _platfromFirestore = platform.MethodChannelFirestore(app: app); - @visibleForTesting - static const MethodChannel channel = MethodChannel( - 'plugins.flutter.io/cloud_firestore', - StandardMethodCodec(FirestoreMessageCodec()), - ); + static MethodChannel get channel => platform.MethodChannelFirestore.channel; - static final Map> _queryObservers = - >{}; - static final Map> _documentObservers = - >{}; + String appName() => _platfromFirestore.appName(); - static final Map _transactionHandlers = - {}; - static int _transactionHandlerId = 0; - @override - bool operator ==(dynamic o) => o is Firestore && o.app == app; + WriteBatch batch() => WriteBatch._(); - @override - int get hashCode => app.hashCode; - /// Gets a [CollectionReference] for the specified Firestore path. CollectionReference collection(String path) { assert(path != null); return CollectionReference._(this, path.split('/')); } - /// Gets a [Query] for the specified collection group. + Query collectionGroup(String path) { - assert(path != null); - assert(!path.contains("/"), "Collection IDs must not contain '/'."); - return Query._( - firestore: this, - isCollectionGroup: true, - pathComponents: path.split('/'), - ); + // TODO: implement collectionGroup + return null; } - /// Gets a [DocumentReference] for the specified Firestore path. + DocumentReference document(String path) { - assert(path != null); - return DocumentReference._(this, path.split('/')); + // TODO: implement document + return null; } - /// Creates a write batch, used for performing multiple writes as a single - /// atomic operation. - /// - /// Unlike transactions, write batches are persisted offline and therefore are - /// preferable when you don’t need to condition your writes on read data. - WriteBatch batch() => WriteBatch._(this); - - /// Executes the given TransactionHandler and then attempts to commit the - /// changes applied within an atomic transaction. - /// - /// In the TransactionHandler, a set of reads and writes can be performed - /// atomically using the Transaction object passed to the TransactionHandler. - /// After the TransactionHandler is run, Firestore will attempt to apply the - /// changes to the server. If any of the data read has been modified outside - /// of this transaction since being read, then the transaction will be - /// retried by executing the updateBlock again. If the transaction still - /// fails after 5 retries, then the transaction will fail. - /// - /// The TransactionHandler may be executed multiple times, it should be able - /// to handle multiple executions. - /// - /// Data accessed with the transaction will not reflect local changes that - /// have not been committed. For this reason, it is required that all - /// reads are performed before any writes. Transactions must be performed - /// while online. Otherwise, reads will fail, and the final commit will fail. - /// - /// By default transactions are limited to 5 seconds of execution time. This - /// timeout can be adjusted by setting the timeout parameter. - Future> runTransaction( - TransactionHandler transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) async { - assert(timeout.inMilliseconds > 0, - 'Transaction timeout must be more than 0 milliseconds'); - final int transactionId = _transactionHandlerId++; - _transactionHandlers[transactionId] = transactionHandler; - final Map result = await channel - .invokeMapMethod( - 'Firestore#runTransaction', { - 'app': app.name, - 'transactionId': transactionId, - 'transactionTimeout': timeout.inMilliseconds - }); - return result ?? {}; + + Future enablePersistence(bool enable) { + // TODO: implement enablePersistence + return null; } - @deprecated - Future enablePersistence(bool enable) async { - assert(enable != null); - await channel - .invokeMethod('Firestore#enablePersistence', { - 'app': app.name, - 'enable': enable, - }); + + Future> runTransaction(transactionHandler, {Duration timeout = const Duration(seconds: 5)}) { + // TODO: implement runTransaction + return null; } - Future settings( - {bool persistenceEnabled, - String host, - bool sslEnabled, - int cacheSizeBytes}) async { - await channel.invokeMethod('Firestore#settings', { - 'app': app.name, - 'persistenceEnabled': persistenceEnabled, - 'host': host, - 'sslEnabled': sslEnabled, - 'cacheSizeBytes': cacheSizeBytes, - }); + Future settings({bool persistenceEnabled, String host, bool sslEnabled, int cacheSizeBytes}) { + // TODO: implement settings + return null; } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 6a41ee7bfec3..92ce33d2daca 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -10,103 +10,22 @@ part of cloud_firestore; /// /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. -class WriteBatch { - WriteBatch._(this._firestore) - : _handle = Firestore.channel.invokeMethod( - 'WriteBatch#create', {'app': _firestore.app.name}); +class WriteBatch implements platform.WriteBatchPlatform { + platform.WriteBatch _delegate; + WriteBatch._(): _delegate = platform.WriteBatch(platform.FirestorePlatform.instance); - final Firestore _firestore; - Future _handle; - final List> _actions = >[]; + @override + Future commit() => _delegate.commit(); - /// Indicator to whether or not this [WriteBatch] has been committed. - bool _committed = false; + @override + void delete(platform.DocumentReference document) => _delegate.delete(document); - /// Commits all of the writes in this write batch as a single atomic unit. - /// - /// Calling this method prevents any future operations from being added. - Future commit() async { - if (!_committed) { - _committed = true; - await Future.wait(_actions); - await Firestore.channel.invokeMethod( - 'WriteBatch#commit', {'handle': await _handle}); - } else { - throw StateError("This batch has already been committed."); - } - } + @override + void setData(platform.DocumentReference document, Map data, {bool merge = false}) => + _delegate.setData(document, data, merge: merge); - /// Deletes the document referred to by [document]. - void delete(DocumentReference document) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - Firestore.channel.invokeMethod( - 'WriteBatch#delete', - { - 'app': _firestore.app.name, - 'handle': handle, - 'path': document.path, - }, - ), - ); - }); - } else { - throw StateError( - "This batch has been committed and can no longer be changed."); - } - } + @override + void updateData(platform.DocumentReference document, Map data) => + _delegate.updateData(document, data); - /// Writes to the document referred to by [document]. - /// - /// If the document does not yet exist, it will be created. - /// - /// If [merge] is true, the provided data will be merged into an - /// existing document instead of overwriting. - void setData(DocumentReference document, Map data, - {bool merge = false}) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - Firestore.channel.invokeMethod( - 'WriteBatch#setData', - { - 'app': _firestore.app.name, - 'handle': handle, - 'path': document.path, - 'data': data, - 'options': {'merge': merge}, - }, - ), - ); - }); - } else { - throw StateError( - "This batch has been committed and can no longer be changed."); - } - } - - /// Updates fields in the document referred to by [document]. - /// - /// If the document does not exist, the operation will fail. - void updateData(DocumentReference document, Map data) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - Firestore.channel.invokeMethod( - 'WriteBatch#updateData', - { - 'app': _firestore.app.name, - 'handle': handle, - 'path': document.path, - 'data': data, - }, - ), - ); - }); - } else { - throw StateError( - "This batch has been committed and can no longer be changed."); - } - } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 6ccce77b47fb..4f1bab08972f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -44,7 +44,6 @@ class MethodChannelFirestore extends FirestorePlatform { static bool _initialized = false; - @visibleForTesting static const MethodChannel channel = MethodChannel( 'plugins.flutter.io/cloud_firestore', StandardMethodCodec(FirestoreMessageCodec()), From 9ad577920299bba9a50c0f718de1785e220397df Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 15:01:00 +0000 Subject: [PATCH 012/144] - create delegate for document related items --- .../lib/src/document_change.dart | 41 +++++---- .../lib/src/document_reference.dart | 91 +++++-------------- .../lib/src/document_snapshot.dart | 14 +-- .../lib/src/firestore_message_codec.dart | 2 +- .../lib/src/snapshot_metadata.dart | 7 +- .../src/method_channel_document_change.dart | 2 +- .../src/method_channel_query_snapshot.dart | 2 +- 7 files changed, 60 insertions(+), 99 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 02f797a65d24..1dbd3b8f3d67 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -23,37 +23,44 @@ enum DocumentChangeType { /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class DocumentChange { - DocumentChange._(Map data, Firestore firestore) - : oldIndex = data['oldIndex'], - newIndex = data['newIndex'], - document = DocumentSnapshot._( - data['path'], - _asStringKeyedMap(data['document']), - SnapshotMetadata._(data["metadata"]["hasPendingWrites"], - data["metadata"]["isFromCache"]), - firestore, - ), - type = DocumentChangeType.values.firstWhere((DocumentChangeType type) { - return type.toString() == data['type']; - }); + final platform.MethodChannelDocumentChange _delegate; + final Firestore _firestore; + + DocumentChange._(Map data, this._firestore) + : _delegate = platform.MethodChannelDocumentChange( + data, platform.FirestorePlatform.instance); /// The type of change that occurred (added, modified, or removed). - final DocumentChangeType type; + DocumentChangeType get type => _fromPlatform(_delegate.type); /// The index of the changed document in the result set immediately prior to /// this [DocumentChange] (i.e. supposing that all prior DocumentChange objects /// have been applied). /// /// -1 for [DocumentChangeType.added] events. - final int oldIndex; + int get oldIndex => _delegate.oldIndex; /// The index of the changed document in the result set immediately after this /// DocumentChange (i.e. supposing that all prior [DocumentChange] objects /// and the current [DocumentChange] object have been applied). /// /// -1 for [DocumentChangeType.removed] events. - final int newIndex; + int get newIndex => _delegate.newIndex; /// The document affected by this change. - final DocumentSnapshot document; + DocumentSnapshot get document => + DocumentSnapshot._(_delegate.document, _firestore); + + DocumentChangeType _fromPlatform(platform.DocumentChangeType platformChange) { + switch (platformChange) { + case platform.DocumentChangeType.added: + return DocumentChangeType.added; + case platform.DocumentChangeType.modified: + return DocumentChangeType.modified; + case platform.DocumentChangeType.removed: + return DocumentChangeType.removed; + default: + throw ArgumentError("Invalud change type"); + } + } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 413cf41be0be..5744daa0906e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -11,8 +11,10 @@ part of cloud_firestore; /// A [DocumentReference] can also be used to create a [CollectionReference] /// to a subcollection. class DocumentReference { + platform.MethodChannelDocumentReference _delegate; DocumentReference._(this.firestore, List pathComponents) : _pathComponents = pathComponents, + _delegate = platform.MethodChannelDocumentReference(platform.FirestorePlatform.instance, pathComponents), assert(firestore != null); /// The Firestore instance associated with this document reference @@ -48,15 +50,7 @@ class DocumentReference { /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. Future setData(Map data, {bool merge = false}) { - return Firestore.channel.invokeMethod( - 'DocumentReference#setData', - { - 'app': firestore.app.name, - 'path': path, - 'data': data, - 'options': {'merge': merge}, - }, - ); + return _delegate.setData(data,merge: merge); } /// Updates fields in the document referred to by this [DocumentReference]. @@ -66,45 +60,34 @@ class DocumentReference { /// /// If no document exists yet, the update will fail. Future updateData(Map data) { - return Firestore.channel.invokeMethod( - 'DocumentReference#updateData', - { - 'app': firestore.app.name, - 'path': path, - 'data': data, - }, - ); + return _delegate.updateData(data); } /// Reads the document referenced by this [DocumentReference]. /// /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { - final Map data = - await Firestore.channel.invokeMapMethod( - 'DocumentReference#get', - { - 'app': firestore.app.name, - 'path': path, - 'source': _getSourceString(source), - }, - ); return DocumentSnapshot._( - data['path'], - _asStringKeyedMap(data['data']), - SnapshotMetadata._(data['metadata']['hasPendingWrites'], - data['metadata']['isFromCache']), + await _delegate.get(source: _fromPlatformSource(source)), firestore, ); } - /// Deletes the document referred to by this [DocumentReference]. - Future delete() { - return Firestore.channel.invokeMethod( - 'DocumentReference#delete', - {'app': firestore.app.name, 'path': path}, - ); + platform.Source _fromPlatformSource(Source platformSource) { + switch(platformSource) { + case Source.cache: + return platform.Source.cache; + case Source.server: + return platform.Source.server; + case Source.serverAndCache: + return platform.Source.serverAndCache; + default: + throw ArgumentError("Invalid source value"); + + } } + /// Deletes the document referred to by this [DocumentReference]. + Future delete() => _delegate.delete(); /// Returns the reference of a collection contained inside of this /// document. @@ -115,37 +98,7 @@ class DocumentReference { } /// Notifies of documents at this location - // TODO(jackson): Reduce code duplication with [Query] - Stream snapshots({bool includeMetadataChanges = false}) { - assert(includeMetadataChanges != null); - Future _handle; - // It's fine to let the StreamController be garbage collected once all the - // subscribers have cancelled; this analyzer warning is safe to ignore. - StreamController controller; // ignore: close_sinks - controller = StreamController.broadcast( - onListen: () { - _handle = Firestore.channel.invokeMethod( - 'DocumentReference#addSnapshotListener', - { - 'app': firestore.app.name, - 'path': path, - 'includeMetadataChanges': includeMetadataChanges, - }, - ).then((dynamic result) => result); - _handle.then((int handle) { - Firestore._documentObservers[handle] = controller; - }); - }, - onCancel: () { - _handle.then((int handle) async { - await Firestore.channel.invokeMethod( - 'removeListener', - {'handle': handle}, - ); - Firestore._documentObservers.remove(handle); - }); - }, - ); - return controller.stream; - } + Stream snapshots({bool includeMetadataChanges = false}) => + _delegate.snapshots(includeMetadataChanges: includeMetadataChanges) + .map((snapshot) => DocumentSnapshot._(snapshot, firestore)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 45508566674a..97245574c10a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -10,26 +10,26 @@ part of cloud_firestore; /// The data can be extracted with the data property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { - DocumentSnapshot._(this._path, this.data, this.metadata, this._firestore); + platform.DocumentSnapshot _deletage; + Firestore _firestore; + DocumentSnapshot._(this._deletage, this._firestore); - final String _path; - final Firestore _firestore; /// The reference that produced this snapshot - DocumentReference get reference => _firestore.document(_path); + DocumentReference get reference => _firestore.document(_deletage.reference.path); /// Contains all the data of this snapshot - final Map data; + Map get data => _deletage.data; /// Metadata about this snapshot concerning its source and if it has local /// modifications. - final SnapshotMetadata metadata; + SnapshotMetadata get metadata=> SnapshotMetadata._(_deletage.metadata); /// Reads individual values from the snapshot dynamic operator [](String key) => data[key]; /// Returns the ID of the snapshot's document - String get documentID => _path.split('/').last; + String get documentID => _deletage.documentID; /// Returns `true` if the document exists. bool get exists => data != null; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart index 9f658cd1c84b..40698f1a8b78 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart @@ -51,7 +51,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putFloat64(value.longitude); } else if (value is DocumentReference) { buffer.putUint8(_kDocumentReference); - final List appName = utf8.encoder.convert(value.firestore.app.name); + final List appName = utf8.encoder.convert(value.firestore.appName()); writeSize(buffer, appName.length); buffer.putUint8List(appName); final List bytes = utf8.encoder.convert(value.path); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart index 4fbae75ac84c..e0017ae93722 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart @@ -6,7 +6,8 @@ part of cloud_firestore; /// Metadata about a snapshot, describing the state of the snapshot. class SnapshotMetadata { - SnapshotMetadata._(this.hasPendingWrites, this.isFromCache); + platform.SnapshotMetadata _delegate; + SnapshotMetadata._(this._delegate); /// Whether the snapshot contains the result of local writes that have not yet /// been committed to the backend. @@ -15,7 +16,7 @@ class SnapshotMetadata { /// `includeMetadataChanges` parameter set to `true` you will receive another /// snapshot with `hasPendingWrites` equal to `false` once the writes have been /// committed to the backend. - final bool hasPendingWrites; + bool get hasPendingWrites => _delegate.hasPendingWrites; /// Whether the snapshot was created from cached data rather than guaranteed /// up-to-date server data. @@ -24,5 +25,5 @@ class SnapshotMetadata { /// `includeMetadataChanges` parameter set to `true` you will receive another /// snapshot with `isFomCache` equal to `false` once the client has received /// up-to-date data from the backend. - final bool isFromCache; + bool get isFromCache => _delegate.isFromCache; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart index c50c63aedbaf..5313e32a714a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart @@ -9,7 +9,7 @@ part of cloud_firestore_platform_interface; /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class MethodChannelDocumentChange extends DocumentChange { - MethodChannelDocumentChange._( + MethodChannelDocumentChange( Map data, FirestorePlatform firestore) : super(DocumentChangeType.values.firstWhere((DocumentChangeType type) { return type.toString() == data['type']; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart index f0b515420dc6..490b382073e5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart @@ -23,7 +23,7 @@ class MethodChannelQuerySnapshot extends QuerySnapshot { }), List.generate(data['documentChanges'].length, (int index) { - return MethodChannelDocumentChange._( + return MethodChannelDocumentChange( data['documentChanges'][index], firestore, ); From 8557df2f0d495b88b782400813cd5d15f4ac2aee Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 16 Dec 2019 15:31:59 +0000 Subject: [PATCH 013/144] - create delegate for transaction and query --- .../cloud_firestore/lib/cloud_firestore.dart | 1 + .../lib/src/document_change.dart | 4 +- .../lib/src/document_reference.dart | 17 +--- .../cloud_firestore/lib/src/firestore.dart | 58 +++++------- .../cloud_firestore/lib/src/query.dart | 92 +++++-------------- .../lib/src/query_snapshot.dart | 38 +++----- .../cloud_firestore/lib/src/transaction.dart | 70 ++++++-------- .../lib/src/utils/PlatformUtils.dart | 17 ++++ .../lib/src/method_channel_firestore.dart | 2 +- .../src/transaction_platform_interface.dart | 2 +- 10 files changed, 113 insertions(+), 188 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 08ab76c2713a..80c730e34b7d 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -22,6 +22,7 @@ export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; +part 'src/utils/PlatformUtils.dart'; part 'src/document_reference.dart'; part 'src/document_snapshot.dart'; part 'src/field_path.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 1dbd3b8f3d67..dd3e7261b4a0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -26,8 +26,8 @@ class DocumentChange { final platform.MethodChannelDocumentChange _delegate; final Firestore _firestore; - DocumentChange._(Map data, this._firestore) - : _delegate = platform.MethodChannelDocumentChange( + DocumentChange._(Map data, this._firestore, {platform.MethodChannelDocumentChange delegate}) + : _delegate = delegate ?? platform.MethodChannelDocumentChange( data, platform.FirestorePlatform.instance); /// The type of change that occurred (added, modified, or removed). diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 5744daa0906e..4ad57b6004d0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -68,25 +68,12 @@ class DocumentReference { /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { return DocumentSnapshot._( - await _delegate.get(source: _fromPlatformSource(source)), + await _delegate.get(source: PlatformUtils._toPlatformSource(source)), firestore, ); } - platform.Source _fromPlatformSource(Source platformSource) { - switch(platformSource) { - case Source.cache: - return platform.Source.cache; - case Source.server: - return platform.Source.server; - case Source.serverAndCache: - return platform.Source.serverAndCache; - default: - throw ArgumentError("Invalid source value"); - - } - } - /// Deletes the document referred to by this [DocumentReference]. + /// Deletes the document referred to by this [DocumentReference]. Future delete() => _delegate.delete(); /// Returns the reference of a collection contained inside of this diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 84b61e5f7ae4..0f708c54ab3d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -8,51 +8,43 @@ part of cloud_firestore; /// /// You can get an instance by calling [Firestore.instance]. class Firestore { - platform.MethodChannelFirestore _platfromFirestore; - Firestore({FirebaseApp app}): _platfromFirestore = platform.MethodChannelFirestore(app: app); + Firestore({FirebaseApp app}) + : _platfromFirestore = platform.MethodChannelFirestore(app: app); static MethodChannel get channel => platform.MethodChannelFirestore.channel; - String appName() => _platfromFirestore.appName(); - WriteBatch batch() => WriteBatch._(); - CollectionReference collection(String path) { assert(path != null); return CollectionReference._(this, path.split('/')); } - - Query collectionGroup(String path) { - // TODO: implement collectionGroup - return null; - } - - - DocumentReference document(String path) { - // TODO: implement document - return null; - } - - - Future enablePersistence(bool enable) { - // TODO: implement enablePersistence - return null; - } - - - Future> runTransaction(transactionHandler, {Duration timeout = const Duration(seconds: 5)}) { - // TODO: implement runTransaction - return null; - } - - Future settings({bool persistenceEnabled, String host, bool sslEnabled, int cacheSizeBytes}) { - // TODO: implement settings - return null; - } + Query collectionGroup(String path) => + Query._(delegate: _platfromFirestore.collectionGroup(path)); + + DocumentReference document(String path) => + DocumentReference._(this, path.split("/")); + + Future enablePersistence(bool enable) => + _platfromFirestore.enablePersistence(enable); + + Future> runTransaction(transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) => + _platfromFirestore.runTransaction(transactionHandler, timeout: timeout); + + Future settings( + {bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) => + _platfromFirestore.settings( + persistenceEnabled: persistenceEnabled, + host: host, + sslEnabled: sslEnabled, + cacheSizeBytes: cacheSizeBytes); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 2da85859ee5a..24ca78203068 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -6,106 +6,64 @@ part of cloud_firestore; /// Represents a query over the data at a particular location. class Query { + final platform.MethodChannelQuery _delegate; + Query._( - {@required this.firestore, - @required List pathComponents, + {this.firestore, + List pathComponents, bool isCollectionGroup = false, - Map parameters}) - : _pathComponents = pathComponents, - _isCollectionGroup = isCollectionGroup, - _parameters = parameters ?? - Map.unmodifiable({ - 'where': List>.unmodifiable(>[]), - 'orderBy': List>.unmodifiable(>[]), - }), + Map parameters, + platform.MethodChannelQuery delegate}) + : _delegate = delegate ?? platform.MethodChannelQuery( + firestore: platform.FirestorePlatform.instance, + pathComponents: pathComponents, + isCollectionGroup: isCollectionGroup, + parameters: parameters), assert(firestore != null), assert(pathComponents != null); /// The Firestore instance associated with this query final Firestore firestore; - final List _pathComponents; - final Map _parameters; - final bool _isCollectionGroup; + List get _pathComponents => _delegate.pathComponents; + Map get _parameters => _delegate.parameters; String get _path => _pathComponents.join('/'); Query _copyWithParameters(Map parameters) { return Query._( firestore: firestore, - isCollectionGroup: _isCollectionGroup, - pathComponents: _pathComponents, + isCollectionGroup: _delegate.isCollectionGroup, + pathComponents: _delegate.pathComponents, parameters: Map.unmodifiable( - Map.from(_parameters)..addAll(parameters), + Map.from(_delegate.parameters)..addAll(parameters), ), ); } Map buildArguments() { - return Map.from(_parameters) - ..addAll({ - 'path': _path, - }); + return _delegate.buildArguments(); } /// Notifies of query results at this location // TODO(jackson): Reduce code duplication with [DocumentReference] - Stream snapshots({bool includeMetadataChanges = false}) { - assert(includeMetadataChanges != null); - Future _handle; - // It's fine to let the StreamController be garbage collected once all the - // subscribers have cancelled; this analyzer warning is safe to ignore. - StreamController controller; // ignore: close_sinks - controller = StreamController.broadcast( - onListen: () { - _handle = Firestore.channel.invokeMethod( - 'Query#addSnapshotListener', - { - 'app': firestore.app.name, - 'path': _path, - 'isCollectionGroup': _isCollectionGroup, - 'parameters': _parameters, - 'includeMetadataChanges': includeMetadataChanges, - }, - ).then((dynamic result) => result); - _handle.then((int handle) { - Firestore._queryObservers[handle] = controller; - }); - }, - onCancel: () { - _handle.then((int handle) async { - await Firestore.channel.invokeMethod( - 'removeListener', - {'handle': handle}, - ); - Firestore._queryObservers.remove(handle); - }); - }, - ); - return controller.stream; - } + Stream snapshots({bool includeMetadataChanges = false}) => + _delegate.snapshots(includeMetadataChanges: includeMetadataChanges).map((item) => QuerySnapshot._(null, firestore, delegate: item)); /// Fetch the documents for this query Future getDocuments( {Source source = Source.serverAndCache}) async { assert(source != null); - final Map data = - await Firestore.channel.invokeMapMethod( - 'Query#getDocuments', - { - 'app': firestore.app.name, - 'path': _path, - 'isCollectionGroup': _isCollectionGroup, - 'parameters': _parameters, - 'source': _getSourceString(source), - }, + return QuerySnapshot._( + null, + firestore, + delegate: await _delegate.getDocuments(source: PlatformUtils._toPlatformSource(source)) ); - return QuerySnapshot._(data, firestore); } /// Obtains a CollectionReference corresponding to this query's location. CollectionReference reference() => - CollectionReference._(firestore, _pathComponents); + CollectionReference._(firestore, _delegate.pathComponents); /// Creates and returns a new [Query] with additional filter on specified /// [field]. [field] refers to a field in a document. @@ -135,7 +93,7 @@ class Query { final ListEquality equality = const ListEquality(); final List> conditions = - List>.from(_parameters['where']); + List>.from(_delegate.parameters['where']); void addCondition(dynamic field, String operator, dynamic value) { final List condition = [field, operator, value]; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 9d6a53fb6f2d..1a5655c8d680 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -6,37 +6,21 @@ part of cloud_firestore; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - QuerySnapshot._(Map data, Firestore firestore) - : documents = List.generate(data['documents'].length, - (int index) { - return DocumentSnapshot._( - data['paths'][index], - _asStringKeyedMap(data['documents'][index]), - SnapshotMetadata._( - data['metadatas'][index]['hasPendingWrites'], - data['metadatas'][index]['isFromCache'], - ), - firestore, - ); - }), - documentChanges = List.generate( - data['documentChanges'].length, (int index) { - return DocumentChange._( - data['documentChanges'][index], - firestore, - ); - }), - metadata = SnapshotMetadata._( - data['metadata']['hasPendingWrites'], - data['metadata']['isFromCache'], - ); + final platform.MethodChannelQuerySnapshot _delegate; + final Firestore _firestore; + + QuerySnapshot._(Map data, this._firestore, {platform.MethodChannelQuerySnapshot delegate}) + : _delegate = delegate ?? platform.MethodChannelQuerySnapshot( + data, platform.FirestorePlatform.instance); /// Gets a list of all the documents included in this snapshot - final List documents; + List get documents => + _delegate.documents.map((item) => DocumentSnapshot._(item, _firestore)); /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. - final List documentChanges; + List get documentChanges => _delegate.documentChanges + .map((item) => DocumentChange._(null, _firestore, delegate: item)); - final SnapshotMetadata metadata; + SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index d13e3f19f9b2..9edc1cad6af6 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -8,12 +8,16 @@ typedef Future TransactionHandler(Transaction transaction); class Transaction { @visibleForTesting - Transaction(this._transactionId, this._firestore); + Transaction(this._transactionId, this._firestore) + : _delegate = platform.Transaction( + _transactionId, platform.FirestorePlatform.instance); + platform.Transaction _delegate; int _transactionId; Firestore _firestore; List> _pendingResults = >[]; - Future _finish() => Future.wait(_pendingResults); + + Future _finish() => _delegate.finish(); /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReference documentReference) { @@ -23,19 +27,11 @@ class Transaction { } Future _get(DocumentReference documentReference) async { - final Map result = await Firestore.channel - .invokeMapMethod('Transaction#get', { - 'app': _firestore.app.name, - 'transactionId': _transactionId, - 'path': documentReference.path, - }); + final result = await _delegate.get(platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/"))); if (result != null) { - return DocumentSnapshot._( - documentReference.path, - result['data']?.cast(), - SnapshotMetadata._(result['metadata']['hasPendingWrites'], - result['metadata']['isFromCache']), - _firestore); + return DocumentSnapshot._(result, _firestore); } else { return null; } @@ -51,14 +47,10 @@ class Transaction { return result; } - Future _delete(DocumentReference documentReference) async { - return Firestore.channel - .invokeMethod('Transaction#delete', { - 'app': _firestore.app.name, - 'transactionId': _transactionId, - 'path': documentReference.path, - }); - } + Future _delete(DocumentReference documentReference) async => + _delegate.delete(platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/"))); /// Updates fields in the document referred to by [documentReference]. /// The update will fail if applied to a document that does not exist. @@ -72,16 +64,13 @@ class Transaction { return result; } - Future _update( - DocumentReference documentReference, Map data) async { - return Firestore.channel - .invokeMethod('Transaction#update', { - 'app': _firestore.app.name, - 'transactionId': _transactionId, - 'path': documentReference.path, - 'data': data, - }); - } + Future _update(DocumentReference documentReference, + Map data) async => + _delegate.update( + platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/")), + data); /// Writes to the document referred to by the provided [DocumentReference]. /// If the document does not exist yet, it will be created. If you pass @@ -96,14 +85,11 @@ class Transaction { return result; } - Future _set( - DocumentReference documentReference, Map data) async { - return Firestore.channel - .invokeMethod('Transaction#set', { - 'app': _firestore.app.name, - 'transactionId': _transactionId, - 'path': documentReference.path, - 'data': data, - }); - } + Future _set(DocumentReference documentReference, + Map data) async => + _delegate.set( + platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/")), + data); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart new file mode 100644 index 000000000000..d9f13ae13574 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart @@ -0,0 +1,17 @@ +part of cloud_firestore; + +class PlatformUtils { + static platform.Source _toPlatformSource(Source platformSource) { + switch(platformSource) { + case Source.cache: + return platform.Source.cache; + case Source.server: + return platform.Source.server; + case Source.serverAndCache: + return platform.Source.serverAndCache; + default: + throw ArgumentError("Invalid source value"); + + } + } +} \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 4f1bab08972f..fbbf862d5325 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -31,7 +31,7 @@ class MethodChannelFirestore extends FirestorePlatform { final Transaction transaction = Transaction(transactionId, this); final dynamic result = await _transactionHandlers[transactionId](transaction); - await transaction._finish(); + await transaction.finish(); return result; } }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart index 129cde52711f..f2cd2668d92b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -13,7 +13,7 @@ abstract class TransactionPlatform { int _transactionId; FirestorePlatform firestore; List> _pendingResults = >[]; - Future _finish() => Future.wait(_pendingResults); + Future finish() => Future.wait(_pendingResults); /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReference documentReference) { From fa06657898c037cf9a73fb6c10c2e3573fbd210b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 07:58:24 +0000 Subject: [PATCH 014/144] delegate cloud_firestore to abstract types --- .../cloud_firestore/.gitignore | 1 + .../cloud_firestore/lib/cloud_firestore.dart | 1 + .../lib/src/collection_reference.dart | 22 +- .../lib/src/document_change.dart | 9 +- .../lib/src/document_reference.dart | 25 +- .../lib/src/document_snapshot.dart | 13 +- .../cloud_firestore/lib/src/firestore.dart | 25 +- .../cloud_firestore/lib/src/query.dart | 266 ++++-------------- .../lib/src/query_snapshot.dart | 13 +- .../cloud_firestore/lib/src/transaction.dart | 9 +- .../lib/src/utils/PlatformUtils.dart | 17 +- .../platform_interface/query_snapshot.dart | 1 + .../cloud_firestore_web/android/.gitignore | 8 - .../cloud_firestore_web/android/build.gradle | 33 --- .../android/gradle.properties | 2 - .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android/settings.gradle | 1 - .../android/src/main/AndroidManifest.xml | 3 - .../FirebaseAuthWebPlugin.java | 15 - .../ios/firebase_auth_web.podspec | 21 -- .../lib/firestore_web.dart | 22 +- .../cloud_firestore_web/lib/query_web.dart | 60 ++-- 22 files changed, 159 insertions(+), 413 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/.gitignore delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/build.gradle delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle.properties delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/settings.gradle delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java delete mode 100644 packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec diff --git a/packages/cloud_firestore/cloud_firestore/.gitignore b/packages/cloud_firestore/cloud_firestore/.gitignore index 46385dab97b6..47b826216be0 100644 --- a/packages/cloud_firestore/cloud_firestore/.gitignore +++ b/packages/cloud_firestore/cloud_firestore/.gitignore @@ -1 +1,2 @@ ios/Classes/UserAgent.h +/example/.flutter-plugins-dependencies diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 80c730e34b7d..883ef34ccb3d 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -9,6 +9,7 @@ import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui' show hashValues, hashList; +import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index fdf7f1291baa..d8b1da33e733 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -8,12 +8,9 @@ part of cloud_firestore; /// document references, and querying for documents (using the methods /// inherited from [Query]). class CollectionReference extends Query { - final platform.MethodChannelCollectionReference _delegate; + final platform.CollectionReference _delegate; - CollectionReference._(Firestore firestore, List pathComponents) - : _delegate = platform.MethodChannelCollectionReference( - platform.FirestorePlatform.instance, pathComponents), - super._(firestore: firestore, pathComponents: pathComponents); + CollectionReference._(this._delegate): super._(_delegate); /// ID of the referenced collection. String get id => _pathComponents.isEmpty ? null : _pathComponents.last; @@ -26,8 +23,7 @@ class CollectionReference extends Query { return null; } return DocumentReference._( - firestore, - (List.from(_pathComponents)..removeLast()), + _delegate.parent() ); } @@ -41,16 +37,8 @@ class CollectionReference extends Query { /// /// The unique key generated is prefixed with a client-generated timestamp /// so that the resulting list will be chronologically-sorted. - DocumentReference document([String path]) { - List childPath; - if (path == null) { - final String key = AutoIdGenerator.autoId(); - childPath = List.from(_pathComponents)..add(key); - } else { - childPath = List.from(_pathComponents)..addAll(path.split(('/'))); - } - return DocumentReference._(firestore, childPath); - } + DocumentReference document([String path]) => + DocumentReference._(_delegate.document(path)); /// Returns a `DocumentReference` with an auto-generated ID, after /// populating it with provided [data]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index dd3e7261b4a0..2af4116a5115 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -23,12 +23,9 @@ enum DocumentChangeType { /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class DocumentChange { - final platform.MethodChannelDocumentChange _delegate; - final Firestore _firestore; + final platform.DocumentChange _delegate; - DocumentChange._(Map data, this._firestore, {platform.MethodChannelDocumentChange delegate}) - : _delegate = delegate ?? platform.MethodChannelDocumentChange( - data, platform.FirestorePlatform.instance); + DocumentChange._(this._delegate); /// The type of change that occurred (added, modified, or removed). DocumentChangeType get type => _fromPlatform(_delegate.type); @@ -49,7 +46,7 @@ class DocumentChange { /// The document affected by this change. DocumentSnapshot get document => - DocumentSnapshot._(_delegate.document, _firestore); + DocumentSnapshot._(_delegate.document); DocumentChangeType _fromPlatform(platform.DocumentChangeType platformChange) { switch (platformChange) { diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 4ad57b6004d0..5e977b4611b8 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -11,37 +11,31 @@ part of cloud_firestore; /// A [DocumentReference] can also be used to create a [CollectionReference] /// to a subcollection. class DocumentReference { - platform.MethodChannelDocumentReference _delegate; - DocumentReference._(this.firestore, List pathComponents) - : _pathComponents = pathComponents, - _delegate = platform.MethodChannelDocumentReference(platform.FirestorePlatform.instance, pathComponents), - assert(firestore != null); + platform.DocumentReference _delegate; + DocumentReference._(this._delegate); /// The Firestore instance associated with this document reference - final Firestore firestore; - - final List _pathComponents; + Firestore get firestore => Firestore.instance; @override bool operator ==(dynamic o) => o is DocumentReference && o.firestore == firestore && o.path == path; @override - int get hashCode => hashList(_pathComponents); + int get hashCode => hashList(_delegate.path.split("/")); /// Parent returns the containing [CollectionReference]. CollectionReference parent() { return CollectionReference._( - firestore, - (List.from(_pathComponents)..removeLast()), + _delegate.parent() ); } /// Slash-delimited path representing the database location of this query. - String get path => _pathComponents.join('/'); + String get path => _delegate.path; /// This document's given or generated ID in the collection. - String get documentID => _pathComponents.last; + String get documentID => _delegate.documentID; /// Writes to the document referred to by this [DocumentReference]. /// @@ -68,8 +62,7 @@ class DocumentReference { /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { return DocumentSnapshot._( - await _delegate.get(source: PlatformUtils._toPlatformSource(source)), - firestore, + await _delegate.get(source: PlatformUtils._toPlatformSource(source)) ); } @@ -87,5 +80,5 @@ class DocumentReference { /// Notifies of documents at this location Stream snapshots({bool includeMetadataChanges = false}) => _delegate.snapshots(includeMetadataChanges: includeMetadataChanges) - .map((snapshot) => DocumentSnapshot._(snapshot, firestore)); + .map((snapshot) => DocumentSnapshot._(snapshot)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 97245574c10a..8d880e56a0ff 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -11,8 +11,8 @@ part of cloud_firestore; /// syntax to access a specific field. class DocumentSnapshot { platform.DocumentSnapshot _deletage; - Firestore _firestore; - DocumentSnapshot._(this._deletage, this._firestore); + Firestore _firestore = Firestore.instance; + DocumentSnapshot._(this._deletage); /// The reference that produced this snapshot @@ -34,12 +34,3 @@ class DocumentSnapshot { /// Returns `true` if the document exists. bool get exists => data != null; } - -Map _asStringKeyedMap(Map map) { - if (map == null) return null; - if (map is Map) { - return map; - } else { - return Map.from(map); - } -} diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 0f708c54ab3d..5a73556f4736 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -7,42 +7,45 @@ part of cloud_firestore; /// The entry point for accessing a Firestore. /// /// You can get an instance by calling [Firestore.instance]. -class Firestore { - platform.MethodChannelFirestore _platfromFirestore; +class Firestore { + + final platform.FirestorePlatform _delegate; - Firestore({FirebaseApp app}) - : _platfromFirestore = platform.MethodChannelFirestore(app: app); + Firestore({FirebaseApp app, platform.FirestorePlatform delegate}) + : _delegate = delegate ?? platform.FirestorePlatform.instance; static MethodChannel get channel => platform.MethodChannelFirestore.channel; - String appName() => _platfromFirestore.appName(); + static Firestore get instance => Firestore(delegate: platform.FirestorePlatform.instance); + + String appName() => _delegate.appName(); WriteBatch batch() => WriteBatch._(); CollectionReference collection(String path) { assert(path != null); - return CollectionReference._(this, path.split('/')); + return CollectionReference._(_delegate.collection(path)); } Query collectionGroup(String path) => - Query._(delegate: _platfromFirestore.collectionGroup(path)); + Query._(_delegate.collectionGroup(path)); DocumentReference document(String path) => - DocumentReference._(this, path.split("/")); + DocumentReference._(_delegate.document(path)); Future enablePersistence(bool enable) => - _platfromFirestore.enablePersistence(enable); + _delegate.enablePersistence(enable); Future> runTransaction(transactionHandler, {Duration timeout = const Duration(seconds: 5)}) => - _platfromFirestore.runTransaction(transactionHandler, timeout: timeout); + _delegate.runTransaction(transactionHandler, timeout: timeout); Future settings( {bool persistenceEnabled, String host, bool sslEnabled, int cacheSizeBytes}) => - _platfromFirestore.settings( + _delegate.settings( persistenceEnabled: persistenceEnabled, host: host, sslEnabled: sslEnabled, diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 24ca78203068..0a67b699e5a6 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -6,64 +6,45 @@ part of cloud_firestore; /// Represents a query over the data at a particular location. class Query { - final platform.MethodChannelQuery _delegate; + final platform.Query _delegate; - Query._( - {this.firestore, - List pathComponents, - bool isCollectionGroup = false, - Map parameters, - platform.MethodChannelQuery delegate}) - : _delegate = delegate ?? platform.MethodChannelQuery( - firestore: platform.FirestorePlatform.instance, - pathComponents: pathComponents, - isCollectionGroup: isCollectionGroup, - parameters: parameters), - assert(firestore != null), - assert(pathComponents != null); + Query._(this._delegate); /// The Firestore instance associated with this query - final Firestore firestore; + Firestore get firestore => Firestore.instance; List get _pathComponents => _delegate.pathComponents; - Map get _parameters => _delegate.parameters; - String get _path => _pathComponents.join('/'); - Query _copyWithParameters(Map parameters) { - return Query._( - firestore: firestore, - isCollectionGroup: _delegate.isCollectionGroup, - pathComponents: _delegate.pathComponents, - parameters: Map.unmodifiable( - Map.from(_delegate.parameters)..addAll(parameters), - ), - ); - } + String get _path => _pathComponents.join('/'); Map buildArguments() { return _delegate.buildArguments(); } /// Notifies of query results at this location - // TODO(jackson): Reduce code duplication with [DocumentReference] Stream snapshots({bool includeMetadataChanges = false}) => - _delegate.snapshots(includeMetadataChanges: includeMetadataChanges).map((item) => QuerySnapshot._(null, firestore, delegate: item)); + _delegate + .snapshots(includeMetadataChanges: includeMetadataChanges) + .map((item) => QuerySnapshot._(item)); /// Fetch the documents for this query Future getDocuments( {Source source = Source.serverAndCache}) async { assert(source != null); - return QuerySnapshot._( - null, - firestore, - delegate: await _delegate.getDocuments(source: PlatformUtils._toPlatformSource(source)) - ); + try{ + final docs = await _delegate.getDocuments(source: PlatformUtils._toPlatformSource(source)); + + return QuerySnapshot._(docs); + }catch(error) { + + throw error; + } } /// Obtains a CollectionReference corresponding to this query's location. CollectionReference reference() => - CollectionReference._(firestore, _delegate.pathComponents); + CollectionReference._(_delegate.reference()); /// Creates and returns a new [Query] with additional filter on specified /// [field]. [field] refers to a field in a document. @@ -87,46 +68,17 @@ class Query { List arrayContainsAny, List whereIn, bool isNull, - }) { - assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); - - final ListEquality equality = const ListEquality(); - final List> conditions = - List>.from(_delegate.parameters['where']); - - void addCondition(dynamic field, String operator, dynamic value) { - final List condition = [field, operator, value]; - assert( - conditions - .where((List item) => equality.equals(condition, item)) - .isEmpty, - 'Condition $condition already exists in this query.'); - conditions.add(condition); - } - - if (isEqualTo != null) addCondition(field, '==', isEqualTo); - if (isLessThan != null) addCondition(field, '<', isLessThan); - if (isLessThanOrEqualTo != null) - addCondition(field, '<=', isLessThanOrEqualTo); - if (isGreaterThan != null) addCondition(field, '>', isGreaterThan); - if (isGreaterThanOrEqualTo != null) - addCondition(field, '>=', isGreaterThanOrEqualTo); - if (arrayContains != null) - addCondition(field, 'array-contains', arrayContains); - if (arrayContainsAny != null) - addCondition(field, 'array-contains-any', arrayContainsAny); - if (whereIn != null) addCondition(field, 'in', whereIn); - if (isNull != null) { - assert( - isNull, - 'isNull can only be set to true. ' - 'Use isEqualTo to filter on non-null values.'); - addCondition(field, '==', null); - } - - return _copyWithParameters({'where': conditions}); - } + }) => + Query._(_delegate.where(field, + isEqualTo: isEqualTo, + isLessThan: isLessThan, + isLessThanOrEqualTo: isLessThanOrEqualTo, + isGreaterThan: isGreaterThan, + isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, + arrayContainsAny: arrayContainsAny, + arrayContains: arrayContains, + whereIn: whereIn, + isNull: isNull)); /// Creates and returns a new [Query] that's additionally sorted by the specified /// [field]. @@ -138,33 +90,8 @@ class Query { /// using [startAfterDocument], [startAtDocument], [endAfterDocument], /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. - Query orderBy(dynamic field, {bool descending = false}) { - assert(field != null && descending != null); - assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); - - final List> orders = - List>.from(_parameters['orderBy']); - - final List order = [field, descending]; - assert(orders.where((List item) => field == item[0]).isEmpty, - 'OrderBy $field already exists in this query'); - - assert(() { - if (field == FieldPath.documentId) { - return !(_parameters.containsKey('startAfterDocument') || - _parameters.containsKey('startAtDocument') || - _parameters.containsKey('endAfterDocument') || - _parameters.containsKey('endAtDocument')); - } - return true; - }(), - '{start/end}{At/After/Before}Document order by document id themselves. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); - - orders.add(order); - return _copyWithParameters({'orderBy': orders}); - } + Query orderBy(dynamic field, {bool descending = false}) => + Query._(_delegate.orderBy(field, descending: descending)); /// Creates and returns a new [Query] that starts after the provided document /// (exclusive). The starting position is relative to the order of the query. @@ -180,26 +107,8 @@ class Query { /// * [endAfterDocument] for a query that ends after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query startAfterDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - assert( - List>.from(_parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAfterDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); - return _copyWithParameters({ - 'startAfterDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - } - }); - } + Query startAfterDocument(DocumentSnapshot documentSnapshot) => + Query._(_delegate.startAfterDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); /// Creates and returns a new [Query] that starts at the provided document /// (inclusive). The starting position is relative to the order of the query. @@ -215,26 +124,9 @@ class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query startAtDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - assert( - List>.from(_parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAtDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); - return _copyWithParameters({ - 'startAtDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - }, - }); - } + Query startAtDocument(DocumentSnapshot documentSnapshot) => + Query._(_delegate.startAtDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); + /// Takes a list of [values], creates and returns a new [Query] that starts /// after the provided fields relative to the order of the query. @@ -244,14 +136,8 @@ class Query { /// Cannot be used in combination with [startAt], [startAfterDocument], or /// [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAfter(List values) { - assert(values != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAfter': values}); - } + Query startAfter(List values) => + Query._(_delegate.startAfter(values)); /// Takes a list of [values], creates and returns a new [Query] that starts at /// the provided fields relative to the order of the query. @@ -261,14 +147,8 @@ class Query { /// Cannot be used in combination with [startAfter], [startAfterDocument], /// or [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAt(List values) { - assert(values != null); - assert(!_parameters.containsKey('startAfter')); - assert(!_parameters.containsKey('startAt')); - assert(!_parameters.containsKey('startAfterDocument')); - assert(!_parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAt': values}); - } + Query startAt(List values) => + Query._(_delegate.startAt(values)); /// Creates and returns a new [Query] that ends at the provided document /// (inclusive). The end position is relative to the order of the query. @@ -284,26 +164,8 @@ class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query endAtDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - assert( - List>.from(_parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endAtDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); - return _copyWithParameters({ - 'endAtDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - }, - }); - } + Query endAtDocument(DocumentSnapshot documentSnapshot) => + Query._(_delegate.endAtDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends at the /// provided fields relative to the order of the query. @@ -313,14 +175,8 @@ class Query { /// Cannot be used in combination with [endBefore], [endBeforeDocument], or /// [endAtDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endAt(List values) { - assert(values != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endAt': values}); - } + Query endAt(List values) => + Query._(_delegate.endAt(values)); /// Creates and returns a new [Query] that ends before the provided document /// (exclusive). The end position is relative to the order of the query. @@ -336,26 +192,8 @@ class Query { /// * [startAfterDocument] for a query that starts after document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query endBeforeDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - assert( - List>.from(_parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endBeforeDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); - return _copyWithParameters({ - 'endBeforeDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data, - }, - }); - } + Query endBeforeDocument(DocumentSnapshot documentSnapshot) => + Query._(_delegate.endBeforeDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends before /// the provided fields relative to the order of the query. @@ -365,19 +203,11 @@ class Query { /// Cannot be used in combination with [endAt], [endBeforeDocument], or /// [endBeforeDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endBefore(List values) { - assert(values != null); - assert(!_parameters.containsKey('endBefore')); - assert(!_parameters.containsKey('endAt')); - assert(!_parameters.containsKey('endBeforeDocument')); - assert(!_parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endBefore': values}); - } + Query endBefore(List values) => + Query._(_delegate.endBefore(values)); /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. - Query limit(int length) { - assert(!_parameters.containsKey('limit')); - return _copyWithParameters({'limit': length}); - } + Query limit(int length) => + Query._(_delegate.limit(length)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 1a5655c8d680..26b34397bab7 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -6,21 +6,20 @@ part of cloud_firestore; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - final platform.MethodChannelQuerySnapshot _delegate; - final Firestore _firestore; + final platform.QuerySnapshot _delegate; - QuerySnapshot._(Map data, this._firestore, {platform.MethodChannelQuerySnapshot delegate}) - : _delegate = delegate ?? platform.MethodChannelQuerySnapshot( - data, platform.FirestorePlatform.instance); + QuerySnapshot._(this._delegate) { + + } /// Gets a list of all the documents included in this snapshot List get documents => - _delegate.documents.map((item) => DocumentSnapshot._(item, _firestore)); + _delegate.documents.map((item) => DocumentSnapshot._(item)).toList(); /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. List get documentChanges => _delegate.documentChanges - .map((item) => DocumentChange._(null, _firestore, delegate: item)); + .map((item) => DocumentChange._(item)).toList(); SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 9edc1cad6af6..40c4fc15913f 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -8,13 +8,12 @@ typedef Future TransactionHandler(Transaction transaction); class Transaction { @visibleForTesting - Transaction(this._transactionId, this._firestore) + Transaction(int transactionId) : _delegate = platform.Transaction( - _transactionId, platform.FirestorePlatform.instance); + transactionId, platform.FirestorePlatform.instance); platform.Transaction _delegate; - int _transactionId; - Firestore _firestore; + List> _pendingResults = >[]; Future _finish() => _delegate.finish(); @@ -31,7 +30,7 @@ class Transaction { platform.FirestorePlatform.instance, documentReference.path.split("/"))); if (result != null) { - return DocumentSnapshot._(result, _firestore); + return DocumentSnapshot._(result); } else { return null; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart index d9f13ae13574..0293d31fa35e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart @@ -2,7 +2,7 @@ part of cloud_firestore; class PlatformUtils { static platform.Source _toPlatformSource(Source platformSource) { - switch(platformSource) { + switch (platformSource) { case Source.cache: return platform.Source.cache; case Source.server: @@ -10,8 +10,19 @@ class PlatformUtils { case Source.serverAndCache: return platform.Source.serverAndCache; default: - throw ArgumentError("Invalid source value"); + throw ArgumentError("Invalid source value"); } } -} \ No newline at end of file + + static platform.DocumentSnapshot _toPlatformDocumentSnapshot( + DocumentSnapshot documentSnapshot) => + platform.DocumentSnapshot( + documentSnapshot.reference.path, + documentSnapshot.data, + platform.SnapshotMetadata( + documentSnapshot.metadata.hasPendingWrites, + documentSnapshot.metadata.isFromCache, + ), + platform.FirestorePlatform.instance); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 5be5ccf59b99..9b315e8f8d3a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -8,6 +8,7 @@ part of cloud_firestore_platform_interface; class QuerySnapshot { QuerySnapshot(this.documents, this.documentChanges, this.metadata); + /// Gets a list of all the documents included in this snapshot final List documents; diff --git a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore deleted file mode 100644 index c6cbe562a427..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle deleted file mode 100644 index be4c5134dc6d..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -group 'io.flutter.plugins.firebaseauth_web' -version '1.0' - -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - } -} - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - - defaultConfig { - minSdkVersion 16 - } - lintOptions { - disable 'InvalidPackage' - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties deleted file mode 100644 index 3148384dab31..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 019065d1d650..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle deleted file mode 100644 index f091fd86b256..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'firebaseauth_web' diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml deleted file mode 100644 index 6f77c56a11e2..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java deleted file mode 100644 index 2caff2952214..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/firebaseauth_web/FirebaseAuthWebPlugin.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.flutter.plugins.firebaseauth_web; - -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.PluginRegistry.Registrar; - -/** FirebaseAuthWebPlugin */ -public class FirebaseAuthWebPlugin implements FlutterPlugin { - @Override - public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {} - - public static void registerWith(Registrar registrar) {} - - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) {} -} diff --git a/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec b/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec deleted file mode 100644 index 2a114b380720..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/ios/firebase_auth_web.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'firebase_auth_web' - s.version = '0.1.0' - s.summary = 'No-op implementation of firebase_auth_web web plugin to avoid build issues on iOS' - s.description = <<-DESC - temp fake firebase_auth_web plugin - DESC - s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_auth/firebase_auth_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/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index a6d74da6e750..d9fb38702951 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,6 +4,7 @@ import 'package:cloud_firestore_web/document_reference_web.dart'; import 'package:cloud_firestore_web/query_web.dart'; import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Settings; +import 'package:flutter/cupertino.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; class FirestoreWeb extends FirestorePlatform { @@ -16,17 +17,16 @@ class FirestoreWeb extends FirestorePlatform { final app = firebase.firestore(); @override - CollectionReference collection(String path) => - CollectionReferenceWeb(this, app, path.split('/')); + CollectionReference collection(String path) { + + return CollectionReferenceWeb(this, app, path.split('/')); + } + @override Query collectionGroup(String path) { - return QueryWeb( - this, - path, - isCollectionGroup: true, - webQuery: app.collectionGroup(path) - ); + return QueryWeb(this, path, + isCollectionGroup: true, webQuery: app.collectionGroup(path)); } @override @@ -49,8 +49,12 @@ class FirestoreWeb extends FirestorePlatform { String host, bool sslEnabled, int cacheSizeBytes}) async { - return app.settings( + return Future.sync(() { + + app.settings( Settings(ssl: sslEnabled, cacheSizeBytes: cacheSizeBytes, host: host)); + + }); } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index dd43714ff828..86758d24fd60 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,5 +1,6 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; +import 'package:flutter/cupertino.dart'; class QueryWeb implements Query { final web.CollectionReference webCollection; @@ -34,7 +35,6 @@ class QueryWeb implements Query { } else if (webCollection != null) { webDocuments = await webCollection.get(); } - return _webQuerySnapshotToQuerySnapshot(webDocuments); } @@ -188,27 +188,41 @@ class QueryWeb implements Query { } QuerySnapshot _webQuerySnapshotToQuerySnapshot( - web.QuerySnapshot webSnapshot) => - QuerySnapshot( - webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot), - webSnapshot.docChanges().map(_webChangeToChange), - _webMetadataToMetada(webSnapshot.metadata)); - - DocumentChange _webChangeToChange(web.DocumentChange webChange) => - DocumentChange( - DocumentChangeType.values.firstWhere((DocumentChangeType type) { - return type.toString() == webChange.type.toLowerCase(); - }), webChange.oldIndex, webChange.newIndex, - _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); + web.QuerySnapshot webSnapshot) { + return QuerySnapshot( + webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot).toList(), + webSnapshot.docChanges().map(_webChangeToChange).toList(), + _webMetadataToMetada(webSnapshot.metadata)); + } + + DocumentChange _webChangeToChange(web.DocumentChange webChange) { + return DocumentChange( + _fromString(webChange.type), webChange.oldIndex, webChange.newIndex, + _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); + } + + DocumentChangeType _fromString(String item) { + switch(item.toLowerCase()) { + case "added": + return DocumentChangeType.added; + case "modified": + return DocumentChangeType.modified; + case "removed": + return DocumentChangeType.removed; + default: + throw ArgumentError("Invalid type"); + } + } DocumentSnapshot _webDocumentSnapshotToDocumentSnapshot( - web.DocumentSnapshot webSnapshot) => - DocumentSnapshot( - webSnapshot.ref.path, - webSnapshot.data(), - SnapshotMetadata(webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache), - this._firestore); + web.DocumentSnapshot webSnapshot) { + return DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata(webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache), + this._firestore); + } web.Query _generateOrderByQuery(DocumentSnapshot webSnapshot) { assert(webQuery != null || webCollection != null); @@ -222,6 +236,8 @@ class QueryWeb implements Query { return query.endAt(fieldValues: webSnapshot.data.values); } - SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) => - SnapshotMetadata(webMetadata.hasPendingWrites, webMetadata.fromCache); + SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { + return SnapshotMetadata( + webMetadata.hasPendingWrites, webMetadata.fromCache); + } } From 993b86aad8b4f87e129d718de76fcb2910683a04 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 09:55:48 +0000 Subject: [PATCH 015/144] - added method_channel_firestore_test - fixed test failure causes --- .../cloud_firestore_platform_interface.dart | 50 +- .../lib/src/firestore_message_codec.dart | 5 +- .../lib/src/method_channel_firestore.dart | 8 +- .../lib/src/method_channel_query.dart | 14 +- .../lib/src/platform_interface/query.dart | 1 + .../method_channel_cloud_firestore_test.dart | 1439 +++++++++++++++++ 6 files changed, 1477 insertions(+), 40 deletions(-) create mode 100755 packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 0e02babae9d6..6019f4dbeeb7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -8,61 +8,46 @@ import 'dart:math'; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; part 'src/method_channel_firestore.dart'; - part 'src/blob.dart'; - part 'src/utils/auto_id_generator.dart'; - part 'src/platform_interface/collection_reference.dart'; part 'src/method_channel_collection_reference.dart'; - part 'src/method_channel_document_change.dart'; part 'src/platform_interface/document_change.dart'; - part 'src/method_channel_document_reference.dart'; - part 'src/platform_interface/document_reference_interface.dart'; - part 'src/document_snapshot.dart'; - part 'src/field_path.dart'; - part 'src/field_value.dart'; - part 'src/firestore_message_codec.dart'; - part 'src/geo_point.dart'; - part 'src/method_channel_query.dart'; - part 'src/platform_interface/query.dart'; - part 'src/platform_interface/query_snapshot.dart'; part 'src/method_channel_query_snapshot.dart'; - part 'src/snapshot_metadata.dart'; - part 'src/source.dart'; - part 'src/timestamp.dart'; - part 'src/transaction.dart'; - part 'src/transaction_platform_interface.dart'; - part 'src/write_batch.dart'; - part 'src/write_batch_platform_interface.dart'; abstract class FirestorePlatform { - FirestorePlatform(); + final FirebaseApp app; + + FirestorePlatform._(this.app); + + factory FirestorePlatform({FirebaseApp app}) { + FirestorePlatform.instance = FirestorePlatform.instance._withApp(app); + return FirestorePlatform.instance; + } /// Only mock implementations should set this to `true`. /// /// Mockito mocks implement this class with `implements` which is forbidden @@ -75,11 +60,6 @@ abstract class FirestorePlatform { static FirestorePlatform _instance = MethodChannelFirestore(); - factory FirestorePlatform._withApp(PlatformFirebaseApp app) => - MethodChannelFirestore(); - - // TODO(amirh): Extract common platform interface logic. - // https://github.com/flutter/flutter/issues/43368 static set instance(FirestorePlatform instance) { if (!instance.isMock) { try { @@ -92,14 +72,18 @@ abstract class FirestorePlatform { _instance = instance; } + FirestorePlatform _withApp(FirebaseApp app) { + throw UnimplementedError("_withApp() not implemented"); + } + String appName() { throw UnimplementedError("appName() not implemented"); } - /// This method ensures that [FirebaseAuthPlatform] isn't implemented with `implements`. + /// This method ensures that [FirestorePlatform] isn't implemented with `implements`. /// /// See class docs for more details on why using `implements` to implement - /// [FirebaseAuthPlatform] is forbidden. + /// [FirestorePlatform] is forbidden. /// /// This private method is called by the [instance] setter, which should fail /// if the provided instance is a class implemented with `implements`. @@ -167,4 +151,10 @@ abstract class FirestorePlatform { int cacheSizeBytes}) async { throw UnimplementedError('settings() is not implemented'); } + + @override + int get hashCode => appName().hashCode; + + @override + bool operator ==(dynamic o) => o is FirestorePlatform && o.app == app; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index c4fd46e98e6d..e97244bd7b93 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -88,9 +88,8 @@ class FirestoreMessageCodec extends StandardMessageCodec { final int appNameLength = readSize(buffer); final String appName = utf8.decoder.convert(buffer.getUint8List(appNameLength)); - //TODO(amr): Fix this. AppName should be used -// final FirebaseCorePlatform app = FirebaseCorePlatform.instance.appNamed(name: appName); - final FirestorePlatform firestore = FirestorePlatform.instance; + final FirebaseApp app = FirebaseApp(name: appName); + final FirestorePlatform firestore = FirestorePlatform(app: app); final int pathLength = readSize(buffer); final String path = utf8.decoder.convert(buffer.getUint8List(pathLength)); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index fbbf862d5325..1213c2c6055a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -8,10 +8,9 @@ part of cloud_firestore_platform_interface; /// /// You can get an instance by calling [Firestore.instance]. class MethodChannelFirestore extends FirestorePlatform { - final FirebaseApp app; MethodChannelFirestore({FirebaseApp app}) - : this.app = app ?? FirebaseApp.instance { + : super._(app ?? FirebaseApp.instance) { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { @@ -59,6 +58,11 @@ class MethodChannelFirestore extends FirestorePlatform { {}; static int _transactionHandlerId = 0; + + @override + FirestorePlatform _withApp(FirebaseApp app) => + MethodChannelFirestore(app: app); + @override CollectionReference collection(String path) { assert(path != null); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index 7b320448e8e9..e0df88dba327 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -5,14 +5,18 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -class MethodChannelQuery extends Query{ +class MethodChannelQuery extends Query { MethodChannelQuery( {@required FirestorePlatform firestore, @required List pathComponents, bool isCollectionGroup = false, Map parameters}) - :super(firestore: firestore, pathComponents: pathComponents, isCollectionGroup: isCollectionGroup, parameters: parameters); - + : super( + firestore: firestore, + pathComponents: pathComponents, + isCollectionGroup: isCollectionGroup, + parameters: parameters, + ); Query _copyWithParameters(Map parameters) { return MethodChannelQuery( @@ -20,11 +24,11 @@ class MethodChannelQuery extends Query{ isCollectionGroup: isCollectionGroup, pathComponents: pathComponents, parameters: Map.unmodifiable( - Map.from(parameters)..addAll(parameters), + Map.from(this.parameters)..addAll(parameters), ), ); } - + // TODO(jackson): Reduce code duplication with [DocumentReference] @override Stream snapshots({bool includeMetadataChanges = false}) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 22055c5ee1a6..e66b67c2a378 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -287,6 +287,7 @@ abstract class Query { .isEmpty, '[endAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); + return _copyWithParameters({ 'endAtDocument': { 'id': documentSnapshot.documentID, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart new file mode 100755 index 000000000000..687871414334 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -0,0 +1,1439 @@ +// Copyright 2017 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 'dart:typed_data'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$MethodChannelFirestore()', () { + int mockHandleId = 0; + FirebaseApp app; + MethodChannelFirestore firestore; + final List log = []; + CollectionReference collectionReference; + Query collectionGroupQuery; + Transaction transaction; + const Map kMockDocumentSnapshotData = { + '1': 2 + }; + const Map kMockSnapshotMetadata = { + "hasPendingWrites": false, + "isFromCache": false, + }; + const MethodChannel firebaseCoreChannel = + MethodChannel('plugins.flutter.io/firebase_core'); + + setUp(() async { + mockHandleId = 0; + // Required for FirebaseApp.configure + firebaseCoreChannel.setMockMethodCallHandler( + (MethodCall methodCall) async {}, + ); + app = await FirebaseApp.configure( + name: 'testApp', + options: const FirebaseOptions( + googleAppID: '1:1234567890:ios:42424242424242', + gcmSenderID: '1234567890', + ), + ); + firestore = MethodChannelFirestore(app: app); + collectionReference = firestore.collection('foo'); + collectionGroupQuery = firestore.collectionGroup('bar'); + transaction = Transaction(0, firestore); + MethodChannelFirestore.channel.setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'Query#addSnapshotListener': + final int handle = mockHandleId++; + // Wait before sending a message back. + // Otherwise the first request didn't have the time to finish. + Future.delayed(Duration.zero).then((_) { + // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. + // https://github.com/flutter/flutter/issues/33446 + // ignore: deprecated_member_use + BinaryMessages.handlePlatformMessage( + MethodChannelFirestore.channel.name, + MethodChannelFirestore.channel.codec.encodeMethodCall( + MethodCall('QuerySnapshot', { + 'app': app.name, + 'handle': handle, + 'paths': ["${methodCall.arguments['path']}/0"], + 'documents': [kMockDocumentSnapshotData], + 'metadatas': >[kMockSnapshotMetadata], + 'metadata': kMockSnapshotMetadata, + 'documentChanges': [ + { + 'oldIndex': -1, + 'newIndex': 0, + 'type': 'DocumentChangeType.added', + 'document': kMockDocumentSnapshotData, + 'metadata': kMockSnapshotMetadata, + }, + ], + }), + ), + (_) {}, + ); + }); + return handle; + case 'DocumentReference#addSnapshotListener': + final int handle = mockHandleId++; + // Wait before sending a message back. + // Otherwise the first request didn't have the time to finish. + Future.delayed(Duration.zero).then((_) { + // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. + // https://github.com/flutter/flutter/issues/33446 + // ignore: deprecated_member_use + BinaryMessages.handlePlatformMessage( + MethodChannelFirestore.channel.name, + MethodChannelFirestore.channel.codec.encodeMethodCall( + MethodCall('DocumentSnapshot', { + 'handle': handle, + 'path': methodCall.arguments['path'], + 'data': kMockDocumentSnapshotData, + 'metadata': kMockSnapshotMetadata, + }), + ), + (_) {}, + ); + }); + return handle; + case 'Query#getDocuments': + return { + 'paths': ["${methodCall.arguments['path']}/0"], + 'documents': [kMockDocumentSnapshotData], + 'metadatas': >[kMockSnapshotMetadata], + 'metadata': kMockSnapshotMetadata, + 'documentChanges': [ + { + 'oldIndex': -1, + 'newIndex': 0, + 'type': 'DocumentChangeType.added', + 'document': kMockDocumentSnapshotData, + 'metadata': kMockSnapshotMetadata, + }, + ], + }; + case 'DocumentReference#setData': + return true; + case 'DocumentReference#get': + if (methodCall.arguments['path'] == 'foo/bar') { + return { + 'path': 'foo/bar', + 'data': {'key1': 'val1'}, + 'metadata': kMockSnapshotMetadata, + }; + } else if (methodCall.arguments['path'] == 'foo/notExists') { + return { + 'path': 'foo/notExists', + 'data': null, + 'metadata': kMockSnapshotMetadata, + }; + } + throw PlatformException(code: 'UNKNOWN_PATH'); + case 'Firestore#runTransaction': + return {'1': 3}; + case 'Transaction#get': + if (methodCall.arguments['path'] == 'foo/bar') { + return { + 'path': 'foo/bar', + 'data': {'key1': 'val1'}, + 'metadata': kMockSnapshotMetadata, + }; + } else if (methodCall.arguments['path'] == 'foo/notExists') { + return { + 'path': 'foo/notExists', + 'data': null, + 'metadata': kMockSnapshotMetadata, + }; + } + throw PlatformException(code: 'UNKNOWN_PATH'); + case 'Transaction#set': + return null; + case 'Transaction#update': + return null; + case 'Transaction#delete': + return null; + case 'WriteBatch#create': + return 1; + default: + return null; + } + }); + log.clear(); + }); + + test('multiple apps', () async { + expect(FirestorePlatform.instance, equals(MethodChannelFirestore())); + final FirebaseApp app = FirebaseApp(name: firestore.app.name); + expect(firestore, equals(MethodChannelFirestore(app: app))); + }); + + test('settings', () async { + final FirebaseApp app = FirebaseApp(name: "testApp2"); + final MethodChannelFirestore firestoreWithSettings = MethodChannelFirestore(app: app); + await firestoreWithSettings.settings( + persistenceEnabled: true, + host: null, + sslEnabled: true, + cacheSizeBytes: 500000, + ); + expect(log, [ + isMethodCall('Firestore#settings', arguments: { + 'app': firestoreWithSettings.app.name, + 'persistenceEnabled': true, + 'host': null, + 'sslEnabled': true, + 'cacheSizeBytes': 500000, + }), + ]); + }); + + group('Transaction', () { + test('runTransaction', () async { + final Map result = await firestore.runTransaction( + (Transaction tx) async {}, + timeout: const Duration(seconds: 3)); + + expect(log, [ + isMethodCall('Firestore#runTransaction', arguments: { + 'app': app.name, + 'transactionId': 0, + 'transactionTimeout': 3000 + }), + ]); + expect(result, equals({'1': 3})); + }); + + test('get', () async { + final DocumentReference documentReference = + firestore.document('foo/bar'); + final DocumentSnapshot snapshot = + await transaction.get(documentReference); + expect(snapshot.reference.firestore, firestore); + expect(log, [ + isMethodCall('Transaction#get', arguments: { + 'app': app.name, + 'transactionId': 0, + 'path': documentReference.path + }) + ]); + }); + + test('get notExists', () async { + final DocumentReference documentReference = + firestore.document('foo/notExists'); + await transaction.get(documentReference); + expect(log, [ + isMethodCall('Transaction#get', arguments: { + 'app': app.name, + 'transactionId': 0, + 'path': documentReference.path + }) + ]); + }); + + test('delete', () async { + final DocumentReference documentReference = + firestore.document('foo/bar'); + await transaction.delete(documentReference); + expect(log, [ + isMethodCall('Transaction#delete', arguments: { + 'app': app.name, + 'transactionId': 0, + 'path': documentReference.path + }) + ]); + }); + + test('update', () async { + final DocumentReference documentReference = + firestore.document('foo/bar'); + final DocumentSnapshot documentSnapshot = await documentReference.get(); + final Map data = documentSnapshot.data; + data['key2'] = 'val2'; + await transaction.set(documentReference, data); + expect(log, [ + isMethodCall('DocumentReference#get', arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'source': 'default', + }), + isMethodCall('Transaction#set', arguments: { + 'app': app.name, + 'transactionId': 0, + 'path': documentReference.path, + 'data': {'key1': 'val1', 'key2': 'val2'} + }) + ]); + }); + + test('set', () async { + final DocumentReference documentReference = + firestore.document('foo/bar'); + final DocumentSnapshot documentSnapshot = await documentReference.get(); + final Map data = documentSnapshot.data; + data['key2'] = 'val2'; + await transaction.set(documentReference, data); + expect(log, [ + isMethodCall('DocumentReference#get', arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'source': 'default', + }), + isMethodCall('Transaction#set', arguments: { + 'app': app.name, + 'transactionId': 0, + 'path': documentReference.path, + 'data': {'key1': 'val1', 'key2': 'val2'} + }) + ]); + }); + }); + + group('Blob', () { + test('hashCode equality', () async { + final Uint8List bytesA = Uint8List(8); + bytesA.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); + final Blob a = Blob(bytesA); + final Uint8List bytesB = Uint8List(8); + bytesB.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); + final Blob b = Blob(bytesB); + expect(a.hashCode == b.hashCode, isTrue); + }); + test('hashCode not equal', () async { + final Uint8List bytesA = Uint8List(8); + bytesA.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); + final Blob a = Blob(bytesA); + final Uint8List bytesB = Uint8List(8); + bytesB.setAll(0, [1, 2, 4, 6, 8, 10, 12, 14]); + final Blob b = Blob(bytesB); + expect(a.hashCode == b.hashCode, isFalse); + }); + }); + + group('CollectionsReference', () { + test('id', () async { + expect(collectionReference.id, equals('foo')); + }); + test('parent', () async { + final DocumentReference docRef = collectionReference.document('bar'); + expect(docRef.parent().id, equals('foo')); + expect(collectionReference.parent(), isNull); + }); + test('path', () async { + expect(collectionReference.path, equals('foo')); + }); + test('listen', () async { + final QuerySnapshot snapshot = await collectionReference + .snapshots(includeMetadataChanges: true) + .first; + final DocumentSnapshot document = snapshot.documents[0]; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + // Flush the async removeListener call + await Future.delayed(Duration.zero); + expect(log, [ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[], + 'orderBy': >[], + }, + 'includeMetadataChanges': true, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]); + }); + test('where', () async { + final StreamSubscription subscription = + collectionReference + .where('createdAt', isLessThan: 100) + .snapshots() + .listen((QuerySnapshot querySnapshot) {}); + subscription.cancel(); + await Future.delayed(Duration.zero); + expect( + log, + equals([ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[ + ['createdAt', '<', 100], + ], + 'orderBy': >[], + + }, + 'includeMetadataChanges': false, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]), + ); + }); + test('where in', () async { + final StreamSubscription subscription = + collectionReference + .where('country', whereIn: ['USA', 'Japan']) + .snapshots() + .listen((QuerySnapshot querySnapshot) {}); + subscription.cancel(); + await Future.delayed(Duration.zero); + expect( + log, + equals([ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[ + [ + 'country', + 'in', + ['USA', 'Japan'] + ], + ], + 'orderBy': >[], + }, + 'includeMetadataChanges': false, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]), + ); + }); + test('where array-contains-any', () async { + final StreamSubscription subscription = + collectionReference + .where('regions', + arrayContainsAny: ['west-coast', 'east-coast']) + .snapshots() + .listen((QuerySnapshot querySnapshot) {}); + subscription.cancel(); + await Future.delayed(Duration.zero); + expect( + log, + equals([ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[ + [ + 'regions', + 'array-contains-any', + ['west-coast', 'east-coast'] + ], + ], + 'orderBy': >[], + + }, + 'includeMetadataChanges': false, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]), + ); + }); + test('where field isNull', () async { + final StreamSubscription subscription = + collectionReference + .where('profile', isNull: true) + .snapshots() + .listen((QuerySnapshot querySnapshot) {}); + subscription.cancel(); + await Future.delayed(Duration.zero); + expect( + log, + equals([ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[ + ['profile', '==', null], + ], + 'orderBy': >[], + }, + 'includeMetadataChanges': false, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]), + ); + }); + test('orderBy', () async { + final StreamSubscription subscription = + collectionReference + .orderBy('createdAt') + .snapshots() + .listen((QuerySnapshot querySnapshot) {}); + subscription.cancel(); + await Future.delayed(Duration.zero); + expect( + log, + equals([ + isMethodCall( + 'Query#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[], + 'orderBy': >[ + ['createdAt', false] + ], + }, + 'includeMetadataChanges': false, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ]), + ); + }); + }); + + group('DocumentReference', () { + test('listen', () async { + final DocumentSnapshot snapshot = await firestore + .document('path/to/foo') + .snapshots(includeMetadataChanges: true) + .first; + expect(snapshot.documentID, equals('foo')); + expect(snapshot.reference.path, equals('path/to/foo')); + expect(snapshot.data, equals(kMockDocumentSnapshotData)); + // Flush the async removeListener call + await Future.delayed(Duration.zero); + expect( + log, + [ + isMethodCall( + 'DocumentReference#addSnapshotListener', + arguments: { + 'app': app.name, + 'path': 'path/to/foo', + 'includeMetadataChanges': true, + }, + ), + isMethodCall( + 'removeListener', + arguments: {'handle': 0}, + ), + ], + ); + }); + test('set', () async { + await collectionReference + .document('bar') + .setData({'bazKey': 'quxValue'}); + expect( + log, + [ + isMethodCall( + 'DocumentReference#setData', + arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + 'options': {'merge': false}, + }, + ), + ], + ); + }); + test('merge set', () async { + await collectionReference + .document('bar') + .setData({'bazKey': 'quxValue'}, merge: true); + expect( + log, + [ + isMethodCall( + 'DocumentReference#setData', + arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + 'options': {'merge': true}, + }, + ), + ], + ); + }); + test('update', () async { + await collectionReference + .document('bar') + .updateData({'bazKey': 'quxValue'}); + expect( + log, + [ + isMethodCall( + 'DocumentReference#updateData', + arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + }, + ), + ], + ); + }); + test('delete', () async { + await collectionReference.document('bar').delete(); + expect( + log, + equals([ + isMethodCall( + 'DocumentReference#delete', + arguments: { + 'app': app.name, + 'path': 'foo/bar', + }, + ), + ]), + ); + }); + test('get', () async { + final DocumentSnapshot snapshot = + await collectionReference.document('bar').get(source: Source.cache); + expect(snapshot.reference.firestore, firestore); + expect( + log, + equals([ + isMethodCall( + 'DocumentReference#get', + arguments: { + 'app': app.name, + 'path': 'foo/bar', + 'source': 'cache', + }, + ), + ]), + ); + log.clear(); + expect(snapshot.reference.path, equals('foo/bar')); + expect(snapshot.data.containsKey('key1'), equals(true)); + expect(snapshot.data['key1'], equals('val1')); + expect(snapshot.exists, isTrue); + + final DocumentSnapshot snapshot2 = await collectionReference + .document('notExists') + .get(source: Source.serverAndCache); + expect(snapshot2.data, isNull); + expect(snapshot2.exists, isFalse); + expect( + log, + equals([ + isMethodCall( + 'DocumentReference#get', + arguments: { + 'app': app.name, + 'path': 'foo/notExists', + 'source': 'default', + }, + ), + ]), + ); + + try { + await collectionReference.document('baz').get(); + } on PlatformException catch (e) { + expect(e.code, equals('UNKNOWN_PATH')); + } + }); + test('collection', () async { + final CollectionReference colRef = + collectionReference.document('bar').collection('baz'); + expect(colRef.path, equals('foo/bar/baz')); + }); + test('parent', () async { + final CollectionReference colRef = + collectionReference.document('bar').collection('baz'); + expect(colRef.parent().documentID, equals('bar')); + }); + }); + + group('Query', () { + test('getDocumentsFromCollection', () async { + QuerySnapshot snapshot = + await collectionReference.getDocuments(source: Source.server); + expect(snapshot.metadata.hasPendingWrites, + equals(kMockSnapshotMetadata['hasPendingWrites'])); + expect(snapshot.metadata.isFromCache, + equals(kMockSnapshotMetadata['isFromCache'])); + DocumentSnapshot document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAtDocument + snapshot = + await collectionReference.startAtDocument(document).getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAfterDocument + snapshot = await collectionReference + .startAfterDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // endAtDocument + snapshot = + await collectionReference.endAtDocument(document).getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // endBeforeDocument + snapshot = await collectionReference + .endBeforeDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAtDocument - endAtDocument + snapshot = await collectionReference + .startAtDocument(document) + .endAtDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('foo/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + expect( + log, + equals( + [ + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'server', + 'parameters': { + 'where': >[], + 'orderBy': >[], + }, + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAtDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + }, + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAfterDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + }, + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'endAtDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + }, + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'endBeforeDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + }, + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAtDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + 'endAtDocument': { + 'id': '0', + 'path': 'foo/0', + 'data': kMockDocumentSnapshotData, + }, + }, + }, + ), + ], + ), + ); + }); + test('getDocumentsFromCollectionGroup', () async { + QuerySnapshot snapshot = await collectionGroupQuery.getDocuments(); + expect(snapshot.metadata.hasPendingWrites, + equals(kMockSnapshotMetadata['hasPendingWrites'])); + expect(snapshot.metadata.isFromCache, + equals(kMockSnapshotMetadata['isFromCache'])); + DocumentSnapshot document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAtDocument + snapshot = + await collectionGroupQuery.startAtDocument(document).getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAfterDocument + snapshot = await collectionGroupQuery + .startAfterDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // endAtDocument + snapshot = + await collectionGroupQuery.endAtDocument(document).getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // endBeforeDocument + snapshot = await collectionGroupQuery + .endBeforeDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + // startAtDocument - endAtDocument + snapshot = await collectionGroupQuery + .startAtDocument(document) + .endAtDocument(document) + .getDocuments(); + document = snapshot.documents.first; + expect(document.documentID, equals('0')); + expect(document.reference.path, equals('bar/0')); + expect(document.data, equals(kMockDocumentSnapshotData)); + + expect( + log, + equals( + [ + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'parameters': { + 'where': >[], + 'orderBy': >[], + }, + 'source': 'default', + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAtDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + }, + 'source': 'default', + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAfterDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + }, + 'source': 'default', + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'endAtDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + }, + 'source': 'default', + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'endBeforeDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + }, + 'source': 'default', + }, + ), + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'bar', + 'isCollectionGroup': true, + 'source': 'default', + 'parameters': { + 'where': >[], + 'orderBy': >[], + 'startAtDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + 'endAtDocument': { + 'id': '0', + 'path': 'bar/0', + 'data': kMockDocumentSnapshotData, + }, + }, + 'source': 'default', + }, + ), + ], + ), + ); + }); + + test('FieldPath', () async { + await collectionReference + .where(FieldPath.documentId, isEqualTo: 'bar') + .getDocuments(); + expect( + log, + equals([ + isMethodCall( + 'Query#getDocuments', + arguments: { + 'app': app.name, + 'path': 'foo', + 'isCollectionGroup': false, + 'parameters': { + 'where': >[ + [FieldPath.documentId, '==', 'bar'], + ], + 'orderBy': >[], + }, + 'source': 'default', + }, + ), + ]), + ); + }); + test('orderBy assertions', () async { + // Can only order by the same field once. + expect(() { + firestore.collection('foo').orderBy('bar').orderBy('bar'); + }, throwsAssertionError); + // Cannot order by unsupported types. + expect(() { + firestore.collection('foo').orderBy(0); + }, throwsAssertionError); + // Parameters cannot be null. + expect(() { + firestore.collection('foo').orderBy(null); + }, throwsAssertionError); + expect(() { + firestore.collection('foo').orderBy('bar', descending: null); + }, throwsAssertionError); + + // Cannot order by document id when paginating with documents. + final DocumentReference documentReference = + firestore.document('foo/bar'); + final DocumentSnapshot snapshot = await documentReference.get(); + expect(() { + firestore + .collection('foo') + .startAfterDocument(snapshot) + .orderBy(FieldPath.documentId); + }, throwsAssertionError); + }); + test('document pagination FieldPath assertions', () async { + final DocumentReference documentReference = + firestore.document('foo/bar'); + final DocumentSnapshot snapshot = await documentReference.get(); + final Query query = + firestore.collection('foo').orderBy(FieldPath.documentId); + + expect(() { + query.startAfterDocument(snapshot); + }, throwsAssertionError); + expect(() { + query.startAtDocument(snapshot); + }, throwsAssertionError); + expect(() { + query.endAtDocument(snapshot); + }, throwsAssertionError); + expect(() { + query.endBeforeDocument(snapshot); + }, throwsAssertionError); + }); + }); + + group('FirestoreMessageCodec', () { + const MessageCodec codec = FirestoreMessageCodec(); + final DateTime testTime = DateTime(2015, 10, 30, 11, 16); + final Timestamp timestamp = Timestamp.fromDate(testTime); + test('should encode and decode simple messages', () { + _checkEncodeDecode(codec, testTime); + _checkEncodeDecode(codec, timestamp); + _checkEncodeDecode( + codec, const GeoPoint(37.421939, -122.083509)); + _checkEncodeDecode(codec, firestore.document('foo/bar')); + }); + test('should encode and decode composite message', () { + final List message = [ + testTime, + const GeoPoint(37.421939, -122.083509), + firestore.document('foo/bar'), + ]; + _checkEncodeDecode(codec, message); + }); + test('encode and decode blob', () { + final Uint8List bytes = Uint8List(4); + bytes[0] = 128; + final Blob message = Blob(bytes); + _checkEncodeDecode(codec, message); + }); + + test('encode and decode FieldValue', () { + _checkEncodeDecode(codec, FieldValue.arrayUnion([123])); + _checkEncodeDecode(codec, FieldValue.arrayRemove([123])); + _checkEncodeDecode(codec, FieldValue.delete()); + _checkEncodeDecode(codec, FieldValue.serverTimestamp()); + _checkEncodeDecode(codec, FieldValue.increment(1.0)); + _checkEncodeDecode(codec, FieldValue.increment(1)); + }); + + test('encode and decode FieldPath', () { + _checkEncodeDecode(codec, FieldPath.documentId); + }); + }); + + group('Timestamp', () { + test('is accurate for dates after epoch', () { + final DateTime date = DateTime.fromMillisecondsSinceEpoch(22501); + final Timestamp timestamp = Timestamp.fromDate(date); + + expect(timestamp.seconds, equals(22)); + expect(timestamp.nanoseconds, equals(501000000)); + }); + + test('is accurate for dates before epoch', () { + final DateTime date = DateTime.fromMillisecondsSinceEpoch(-1250); + final Timestamp timestamp = Timestamp.fromDate(date); + + expect(timestamp.seconds, equals(-2)); + expect(timestamp.nanoseconds, equals(750000000)); + }); + + test('creates equivalent timestamps regardless of factory', () { + const int kMilliseconds = 22501; + const int kMicroseconds = 22501000; + final DateTime date = + DateTime.fromMicrosecondsSinceEpoch(kMicroseconds); + + final Timestamp timestamp = Timestamp(22, 501000000); + final Timestamp milliTimestamp = + Timestamp.fromMillisecondsSinceEpoch(kMilliseconds); + final Timestamp microTimestamp = + Timestamp.fromMicrosecondsSinceEpoch(kMicroseconds); + final Timestamp dateTimestamp = Timestamp.fromDate(date); + + expect(timestamp, equals(milliTimestamp)); + expect(milliTimestamp, equals(microTimestamp)); + expect(microTimestamp, equals(dateTimestamp)); + }); + + test('correctly compares timestamps', () { + final Timestamp alpha = Timestamp.fromDate(DateTime(2017, 5, 11)); + final Timestamp beta1 = Timestamp.fromDate(DateTime(2018, 2, 19)); + final Timestamp beta2 = Timestamp.fromDate(DateTime(2018, 4, 2)); + final Timestamp beta3 = Timestamp.fromDate(DateTime(2018, 4, 20)); + final Timestamp preview = Timestamp.fromDate(DateTime(2018, 6, 20)); + final List inOrder = [ + alpha, + beta1, + beta2, + beta3, + preview + ]; + + final List timestamps = [ + beta2, + beta3, + alpha, + preview, + beta1 + ]; + timestamps.sort(); + expect(_deepEqualsList(timestamps, inOrder), isTrue); + }); + + test('rejects dates outside RFC 3339 range', () { + final List invalidDates = [ + DateTime.fromMillisecondsSinceEpoch(-70000000000000), + DateTime.fromMillisecondsSinceEpoch(300000000000000), + ]; + + invalidDates.forEach((DateTime date) { + expect(() => Timestamp.fromDate(date), throwsArgumentError); + }); + }); + }); + + group('WriteBatch', () { + test('set', () async { + final WriteBatch batch = firestore.batch(); + batch.setData( + collectionReference.document('bar'), + {'bazKey': 'quxValue'}, + ); + await batch.commit(); + expect( + log, + [ + isMethodCall('WriteBatch#create', arguments: { + 'app': app.name, + }), + isMethodCall( + 'WriteBatch#setData', + arguments: { + 'app': app.name, + 'handle': 1, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + 'options': {'merge': false}, + }, + ), + isMethodCall( + 'WriteBatch#commit', + arguments: { + 'handle': 1, + }, + ), + ], + ); + }); + test('merge set', () async { + final WriteBatch batch = firestore.batch(); + batch.setData( + collectionReference.document('bar'), + {'bazKey': 'quxValue'}, + merge: true, + ); + await batch.commit(); + expect( + log, + [ + isMethodCall('WriteBatch#create', arguments: { + 'app': app.name, + }), + isMethodCall('WriteBatch#setData', arguments: { + 'app': app.name, + 'handle': 1, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + 'options': {'merge': true}, + }), + isMethodCall( + 'WriteBatch#commit', + arguments: { + 'handle': 1, + }, + ), + ], + ); + }); + test('update', () async { + final WriteBatch batch = firestore.batch(); + batch.updateData( + collectionReference.document('bar'), + {'bazKey': 'quxValue'}, + ); + await batch.commit(); + expect( + log, + [ + isMethodCall( + 'WriteBatch#create', + arguments: { + 'app': app.name, + }, + ), + isMethodCall( + 'WriteBatch#updateData', + arguments: { + 'app': app.name, + 'handle': 1, + 'path': 'foo/bar', + 'data': {'bazKey': 'quxValue'}, + }, + ), + isMethodCall( + 'WriteBatch#commit', + arguments: { + 'handle': 1, + }, + ), + ], + ); + }); + test('delete', () async { + final WriteBatch batch = firestore.batch(); + batch.delete(collectionReference.document('bar')); + await batch.commit(); + expect( + log, + [ + isMethodCall( + 'WriteBatch#create', + arguments: { + 'app': app.name, + }, + ), + isMethodCall( + 'WriteBatch#delete', + arguments: { + 'app': app.name, + 'handle': 1, + 'path': 'foo/bar', + }, + ), + isMethodCall( + 'WriteBatch#commit', + arguments: { + 'handle': 1, + }, + ), + ], + ); + }); + }); + }); +} + +void _checkEncodeDecode(MessageCodec codec, T message) { + final ByteData encoded = codec.encodeMessage(message); + final T decoded = codec.decodeMessage(encoded); + if (message == null) { + expect(encoded, isNull); + expect(decoded, isNull); + } else { + expect(_deepEquals(message, decoded), isTrue); + final ByteData encodedAgain = codec.encodeMessage(decoded); + expect( + encodedAgain.buffer.asUint8List(), + orderedEquals(encoded.buffer.asUint8List()), + ); + } +} + +bool _deepEquals(dynamic valueA, dynamic valueB) { + if (valueA is TypedData) + return valueB is TypedData && _deepEqualsTypedData(valueA, valueB); + if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); + if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); + if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; + if (valueA is FieldValue) { + return valueB is FieldValue && _deepEqualsFieldValue(valueA, valueB); + } + if (valueA is FieldPath) + return valueB is FieldPath && valueA.type == valueB.type; + return valueA == valueB; +} + +bool _deepEqualsTypedData(TypedData valueA, TypedData valueB) { + if (valueA is ByteData) { + return valueB is ByteData && + _deepEqualsList( + valueA.buffer.asUint8List(), valueB.buffer.asUint8List()); + } + if (valueA is Uint8List) + return valueB is Uint8List && _deepEqualsList(valueA, valueB); + if (valueA is Int32List) + return valueB is Int32List && _deepEqualsList(valueA, valueB); + if (valueA is Int64List) + return valueB is Int64List && _deepEqualsList(valueA, valueB); + if (valueA is Float64List) + return valueB is Float64List && _deepEqualsList(valueA, valueB); + throw 'Unexpected typed data: $valueA'; +} + +bool _deepEqualsList(List valueA, List valueB) { + if (valueA.length != valueB.length) return false; + for (int i = 0; i < valueA.length; i++) { + if (!_deepEquals(valueA[i], valueB[i])) return false; + } + return true; +} + +bool _deepEqualsMap( + Map valueA, Map valueB) { + if (valueA.length != valueB.length) return false; + for (final dynamic key in valueA.keys) { + if (!valueB.containsKey(key) || !_deepEquals(valueA[key], valueB[key])) + return false; + } + return true; +} + +bool _deepEqualsFieldValue(FieldValue valueA, FieldValue valueB) { + if (valueA.type != valueB.type) return false; + if (valueA.value == null) return valueB.value == null; + if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); + if (valueA.value is Map) return _deepEqualsMap(valueA.value, valueB.value); + return valueA.value == valueB.value; +} From 2a160d55f11fa49e87ba664ff52e44c4e60d6e65 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 10:18:59 +0000 Subject: [PATCH 016/144] Use support multiple apps in FirestoreWeb --- .../test/cloud_firestore_test.dart | 1437 ----------------- .../cloud_firestore_platform_interface.dart | 8 +- .../lib/src/firestore_message_codec.dart | 2 +- .../lib/src/method_channel_firestore.dart | 4 +- .../lib/firestore_web.dart | 32 +- .../cloud_firestore_web/pubspec.yaml | 2 +- 6 files changed, 25 insertions(+), 1460 deletions(-) delete mode 100755 packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart diff --git a/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart deleted file mode 100755 index 328427f46e04..000000000000 --- a/packages/cloud_firestore/cloud_firestore/test/cloud_firestore_test.dart +++ /dev/null @@ -1,1437 +0,0 @@ -// Copyright 2017 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 'dart:typed_data'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - group('$Firestore', () { - int mockHandleId = 0; - FirebaseApp app; - Firestore firestore; - final List log = []; - CollectionReference collectionReference; - Query collectionGroupQuery; - Transaction transaction; - const Map kMockDocumentSnapshotData = { - '1': 2 - }; - const Map kMockSnapshotMetadata = { - "hasPendingWrites": false, - "isFromCache": false, - }; - const MethodChannel firebaseCoreChannel = - MethodChannel('plugins.flutter.io/firebase_core'); - - setUp(() async { - mockHandleId = 0; - // Required for FirebaseApp.configure - firebaseCoreChannel.setMockMethodCallHandler( - (MethodCall methodCall) async {}, - ); - app = await FirebaseApp.configure( - name: 'testApp', - options: const FirebaseOptions( - googleAppID: '1:1234567890:ios:42424242424242', - gcmSenderID: '1234567890', - ), - ); - firestore = Firestore(app: app); - collectionReference = firestore.collection('foo'); - collectionGroupQuery = firestore.collectionGroup('bar'); - transaction = Transaction(0, firestore); - Firestore.channel.setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - switch (methodCall.method) { - case 'Query#addSnapshotListener': - final int handle = mockHandleId++; - // Wait before sending a message back. - // Otherwise the first request didn't have the time to finish. - Future.delayed(Duration.zero).then((_) { - // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. - // https://github.com/flutter/flutter/issues/33446 - // ignore: deprecated_member_use - BinaryMessages.handlePlatformMessage( - Firestore.channel.name, - Firestore.channel.codec.encodeMethodCall( - MethodCall('QuerySnapshot', { - 'app': app.name, - 'handle': handle, - 'paths': ["${methodCall.arguments['path']}/0"], - 'documents': [kMockDocumentSnapshotData], - 'metadatas': >[kMockSnapshotMetadata], - 'metadata': kMockSnapshotMetadata, - 'documentChanges': [ - { - 'oldIndex': -1, - 'newIndex': 0, - 'type': 'DocumentChangeType.added', - 'document': kMockDocumentSnapshotData, - 'metadata': kMockSnapshotMetadata, - }, - ], - }), - ), - (_) {}, - ); - }); - return handle; - case 'DocumentReference#addSnapshotListener': - final int handle = mockHandleId++; - // Wait before sending a message back. - // Otherwise the first request didn't have the time to finish. - Future.delayed(Duration.zero).then((_) { - // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. - // https://github.com/flutter/flutter/issues/33446 - // ignore: deprecated_member_use - BinaryMessages.handlePlatformMessage( - Firestore.channel.name, - Firestore.channel.codec.encodeMethodCall( - MethodCall('DocumentSnapshot', { - 'handle': handle, - 'path': methodCall.arguments['path'], - 'data': kMockDocumentSnapshotData, - 'metadata': kMockSnapshotMetadata, - }), - ), - (_) {}, - ); - }); - return handle; - case 'Query#getDocuments': - return { - 'paths': ["${methodCall.arguments['path']}/0"], - 'documents': [kMockDocumentSnapshotData], - 'metadatas': >[kMockSnapshotMetadata], - 'metadata': kMockSnapshotMetadata, - 'documentChanges': [ - { - 'oldIndex': -1, - 'newIndex': 0, - 'type': 'DocumentChangeType.added', - 'document': kMockDocumentSnapshotData, - 'metadata': kMockSnapshotMetadata, - }, - ], - }; - case 'DocumentReference#setData': - return true; - case 'DocumentReference#get': - if (methodCall.arguments['path'] == 'foo/bar') { - return { - 'path': 'foo/bar', - 'data': {'key1': 'val1'}, - 'metadata': kMockSnapshotMetadata, - }; - } else if (methodCall.arguments['path'] == 'foo/notExists') { - return { - 'path': 'foo/notExists', - 'data': null, - 'metadata': kMockSnapshotMetadata, - }; - } - throw PlatformException(code: 'UNKNOWN_PATH'); - case 'Firestore#runTransaction': - return {'1': 3}; - case 'Transaction#get': - if (methodCall.arguments['path'] == 'foo/bar') { - return { - 'path': 'foo/bar', - 'data': {'key1': 'val1'}, - 'metadata': kMockSnapshotMetadata, - }; - } else if (methodCall.arguments['path'] == 'foo/notExists') { - return { - 'path': 'foo/notExists', - 'data': null, - 'metadata': kMockSnapshotMetadata, - }; - } - throw PlatformException(code: 'UNKNOWN_PATH'); - case 'Transaction#set': - return null; - case 'Transaction#update': - return null; - case 'Transaction#delete': - return null; - case 'WriteBatch#create': - return 1; - default: - return null; - } - }); - log.clear(); - }); - - test('multiple apps', () async { - expect(Firestore.instance, equals(Firestore())); - final FirebaseApp app = FirebaseApp(name: firestore.app.name); - expect(firestore, equals(Firestore(app: app))); - }); - - test('settings', () async { - final FirebaseApp app = FirebaseApp(name: "testApp2"); - final Firestore firestoreWithSettings = Firestore(app: app); - await firestoreWithSettings.settings( - persistenceEnabled: true, - host: null, - sslEnabled: true, - cacheSizeBytes: 500000, - ); - expect(log, [ - isMethodCall('Firestore#settings', arguments: { - 'app': firestoreWithSettings.app.name, - 'persistenceEnabled': true, - 'host': null, - 'sslEnabled': true, - 'cacheSizeBytes': 500000, - }), - ]); - }); - - group('Transaction', () { - test('runTransaction', () async { - final Map result = await firestore.runTransaction( - (Transaction tx) async {}, - timeout: const Duration(seconds: 3)); - - expect(log, [ - isMethodCall('Firestore#runTransaction', arguments: { - 'app': app.name, - 'transactionId': 0, - 'transactionTimeout': 3000 - }), - ]); - expect(result, equals({'1': 3})); - }); - - test('get', () async { - final DocumentReference documentReference = - firestore.document('foo/bar'); - final DocumentSnapshot snapshot = - await transaction.get(documentReference); - expect(snapshot.reference.firestore, firestore); - expect(log, [ - isMethodCall('Transaction#get', arguments: { - 'app': app.name, - 'transactionId': 0, - 'path': documentReference.path - }) - ]); - }); - - test('get notExists', () async { - final DocumentReference documentReference = - firestore.document('foo/notExists'); - await transaction.get(documentReference); - expect(log, [ - isMethodCall('Transaction#get', arguments: { - 'app': app.name, - 'transactionId': 0, - 'path': documentReference.path - }) - ]); - }); - - test('delete', () async { - final DocumentReference documentReference = - firestore.document('foo/bar'); - await transaction.delete(documentReference); - expect(log, [ - isMethodCall('Transaction#delete', arguments: { - 'app': app.name, - 'transactionId': 0, - 'path': documentReference.path - }) - ]); - }); - - test('update', () async { - final DocumentReference documentReference = - firestore.document('foo/bar'); - final DocumentSnapshot documentSnapshot = await documentReference.get(); - final Map data = documentSnapshot.data; - data['key2'] = 'val2'; - await transaction.set(documentReference, data); - expect(log, [ - isMethodCall('DocumentReference#get', arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'source': 'default', - }), - isMethodCall('Transaction#set', arguments: { - 'app': app.name, - 'transactionId': 0, - 'path': documentReference.path, - 'data': {'key1': 'val1', 'key2': 'val2'} - }) - ]); - }); - - test('set', () async { - final DocumentReference documentReference = - firestore.document('foo/bar'); - final DocumentSnapshot documentSnapshot = await documentReference.get(); - final Map data = documentSnapshot.data; - data['key2'] = 'val2'; - await transaction.set(documentReference, data); - expect(log, [ - isMethodCall('DocumentReference#get', arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'source': 'default', - }), - isMethodCall('Transaction#set', arguments: { - 'app': app.name, - 'transactionId': 0, - 'path': documentReference.path, - 'data': {'key1': 'val1', 'key2': 'val2'} - }) - ]); - }); - }); - - group('Blob', () { - test('hashCode equality', () async { - final Uint8List bytesA = Uint8List(8); - bytesA.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); - final Blob a = Blob(bytesA); - final Uint8List bytesB = Uint8List(8); - bytesB.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); - final Blob b = Blob(bytesB); - expect(a.hashCode == b.hashCode, isTrue); - }); - test('hashCode not equal', () async { - final Uint8List bytesA = Uint8List(8); - bytesA.setAll(0, [0, 2, 4, 6, 8, 10, 12, 14]); - final Blob a = Blob(bytesA); - final Uint8List bytesB = Uint8List(8); - bytesB.setAll(0, [1, 2, 4, 6, 8, 10, 12, 14]); - final Blob b = Blob(bytesB); - expect(a.hashCode == b.hashCode, isFalse); - }); - }); - - group('CollectionsReference', () { - test('id', () async { - expect(collectionReference.id, equals('foo')); - }); - test('parent', () async { - final DocumentReference docRef = collectionReference.document('bar'); - expect(docRef.parent().id, equals('foo')); - expect(collectionReference.parent(), isNull); - }); - test('path', () async { - expect(collectionReference.path, equals('foo')); - }); - test('listen', () async { - final QuerySnapshot snapshot = await collectionReference - .snapshots(includeMetadataChanges: true) - .first; - final DocumentSnapshot document = snapshot.documents[0]; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - // Flush the async removeListener call - await Future.delayed(Duration.zero); - expect(log, [ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[], - 'orderBy': >[], - }, - 'includeMetadataChanges': true, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]); - }); - test('where', () async { - final StreamSubscription subscription = - collectionReference - .where('createdAt', isLessThan: 100) - .snapshots() - .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); - await Future.delayed(Duration.zero); - expect( - log, - equals([ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[ - ['createdAt', '<', 100], - ], - 'orderBy': >[], - }, - 'includeMetadataChanges': false, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]), - ); - }); - test('where in', () async { - final StreamSubscription subscription = - collectionReference - .where('country', whereIn: ['USA', 'Japan']) - .snapshots() - .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); - await Future.delayed(Duration.zero); - expect( - log, - equals([ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[ - [ - 'country', - 'in', - ['USA', 'Japan'] - ], - ], - 'orderBy': >[], - }, - 'includeMetadataChanges': false, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]), - ); - }); - test('where array-contains-any', () async { - final StreamSubscription subscription = - collectionReference - .where('regions', - arrayContainsAny: ['west-coast', 'east-coast']) - .snapshots() - .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); - await Future.delayed(Duration.zero); - expect( - log, - equals([ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[ - [ - 'regions', - 'array-contains-any', - ['west-coast', 'east-coast'] - ], - ], - 'orderBy': >[], - }, - 'includeMetadataChanges': false, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]), - ); - }); - test('where field isNull', () async { - final StreamSubscription subscription = - collectionReference - .where('profile', isNull: true) - .snapshots() - .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); - await Future.delayed(Duration.zero); - expect( - log, - equals([ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[ - ['profile', '==', null], - ], - 'orderBy': >[], - }, - 'includeMetadataChanges': false, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]), - ); - }); - test('orderBy', () async { - final StreamSubscription subscription = - collectionReference - .orderBy('createdAt') - .snapshots() - .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); - await Future.delayed(Duration.zero); - expect( - log, - equals([ - isMethodCall( - 'Query#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[], - 'orderBy': >[ - ['createdAt', false] - ], - }, - 'includeMetadataChanges': false, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ]), - ); - }); - }); - - group('DocumentReference', () { - test('listen', () async { - final DocumentSnapshot snapshot = await firestore - .document('path/to/foo') - .snapshots(includeMetadataChanges: true) - .first; - expect(snapshot.documentID, equals('foo')); - expect(snapshot.reference.path, equals('path/to/foo')); - expect(snapshot.data, equals(kMockDocumentSnapshotData)); - // Flush the async removeListener call - await Future.delayed(Duration.zero); - expect( - log, - [ - isMethodCall( - 'DocumentReference#addSnapshotListener', - arguments: { - 'app': app.name, - 'path': 'path/to/foo', - 'includeMetadataChanges': true, - }, - ), - isMethodCall( - 'removeListener', - arguments: {'handle': 0}, - ), - ], - ); - }); - test('set', () async { - await collectionReference - .document('bar') - .setData({'bazKey': 'quxValue'}); - expect( - log, - [ - isMethodCall( - 'DocumentReference#setData', - arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - 'options': {'merge': false}, - }, - ), - ], - ); - }); - test('merge set', () async { - await collectionReference - .document('bar') - .setData({'bazKey': 'quxValue'}, merge: true); - expect( - log, - [ - isMethodCall( - 'DocumentReference#setData', - arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - 'options': {'merge': true}, - }, - ), - ], - ); - }); - test('update', () async { - await collectionReference - .document('bar') - .updateData({'bazKey': 'quxValue'}); - expect( - log, - [ - isMethodCall( - 'DocumentReference#updateData', - arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - }, - ), - ], - ); - }); - test('delete', () async { - await collectionReference.document('bar').delete(); - expect( - log, - equals([ - isMethodCall( - 'DocumentReference#delete', - arguments: { - 'app': app.name, - 'path': 'foo/bar', - }, - ), - ]), - ); - }); - test('get', () async { - final DocumentSnapshot snapshot = - await collectionReference.document('bar').get(source: Source.cache); - expect(snapshot.reference.firestore, firestore); - expect( - log, - equals([ - isMethodCall( - 'DocumentReference#get', - arguments: { - 'app': app.name, - 'path': 'foo/bar', - 'source': 'cache', - }, - ), - ]), - ); - log.clear(); - expect(snapshot.reference.path, equals('foo/bar')); - expect(snapshot.data.containsKey('key1'), equals(true)); - expect(snapshot.data['key1'], equals('val1')); - expect(snapshot.exists, isTrue); - - final DocumentSnapshot snapshot2 = await collectionReference - .document('notExists') - .get(source: Source.serverAndCache); - expect(snapshot2.data, isNull); - expect(snapshot2.exists, isFalse); - expect( - log, - equals([ - isMethodCall( - 'DocumentReference#get', - arguments: { - 'app': app.name, - 'path': 'foo/notExists', - 'source': 'default', - }, - ), - ]), - ); - - try { - await collectionReference.document('baz').get(); - } on PlatformException catch (e) { - expect(e.code, equals('UNKNOWN_PATH')); - } - }); - test('collection', () async { - final CollectionReference colRef = - collectionReference.document('bar').collection('baz'); - expect(colRef.path, equals('foo/bar/baz')); - }); - test('parent', () async { - final CollectionReference colRef = - collectionReference.document('bar').collection('baz'); - expect(colRef.parent().documentID, equals('bar')); - }); - }); - - group('Query', () { - test('getDocumentsFromCollection', () async { - QuerySnapshot snapshot = - await collectionReference.getDocuments(source: Source.server); - expect(snapshot.metadata.hasPendingWrites, - equals(kMockSnapshotMetadata['hasPendingWrites'])); - expect(snapshot.metadata.isFromCache, - equals(kMockSnapshotMetadata['isFromCache'])); - DocumentSnapshot document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAtDocument - snapshot = - await collectionReference.startAtDocument(document).getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAfterDocument - snapshot = await collectionReference - .startAfterDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // endAtDocument - snapshot = - await collectionReference.endAtDocument(document).getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // endBeforeDocument - snapshot = await collectionReference - .endBeforeDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAtDocument - endAtDocument - snapshot = await collectionReference - .startAtDocument(document) - .endAtDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('foo/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - expect( - log, - equals( - [ - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'server', - 'parameters': { - 'where': >[], - 'orderBy': >[], - }, - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAtDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - }, - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAfterDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - }, - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'endAtDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - }, - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'endBeforeDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - }, - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAtDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - 'endAtDocument': { - 'id': '0', - 'path': 'foo/0', - 'data': kMockDocumentSnapshotData, - }, - }, - }, - ), - ], - ), - ); - }); - test('getDocumentsFromCollectionGroup', () async { - QuerySnapshot snapshot = await collectionGroupQuery.getDocuments(); - expect(snapshot.metadata.hasPendingWrites, - equals(kMockSnapshotMetadata['hasPendingWrites'])); - expect(snapshot.metadata.isFromCache, - equals(kMockSnapshotMetadata['isFromCache'])); - DocumentSnapshot document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAtDocument - snapshot = - await collectionGroupQuery.startAtDocument(document).getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAfterDocument - snapshot = await collectionGroupQuery - .startAfterDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // endAtDocument - snapshot = - await collectionGroupQuery.endAtDocument(document).getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // endBeforeDocument - snapshot = await collectionGroupQuery - .endBeforeDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - // startAtDocument - endAtDocument - snapshot = await collectionGroupQuery - .startAtDocument(document) - .endAtDocument(document) - .getDocuments(); - document = snapshot.documents.first; - expect(document.documentID, equals('0')); - expect(document.reference.path, equals('bar/0')); - expect(document.data, equals(kMockDocumentSnapshotData)); - - expect( - log, - equals( - [ - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'parameters': { - 'where': >[], - 'orderBy': >[], - }, - 'source': 'default', - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAtDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - }, - 'source': 'default', - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAfterDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - }, - 'source': 'default', - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'endAtDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - }, - 'source': 'default', - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'endBeforeDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - }, - 'source': 'default', - }, - ), - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'bar', - 'isCollectionGroup': true, - 'source': 'default', - 'parameters': { - 'where': >[], - 'orderBy': >[], - 'startAtDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - 'endAtDocument': { - 'id': '0', - 'path': 'bar/0', - 'data': kMockDocumentSnapshotData, - }, - }, - 'source': 'default', - }, - ), - ], - ), - ); - }); - - test('FieldPath', () async { - await collectionReference - .where(FieldPath.documentId, isEqualTo: 'bar') - .getDocuments(); - expect( - log, - equals([ - isMethodCall( - 'Query#getDocuments', - arguments: { - 'app': app.name, - 'path': 'foo', - 'isCollectionGroup': false, - 'parameters': { - 'where': >[ - [FieldPath.documentId, '==', 'bar'], - ], - 'orderBy': >[], - }, - 'source': 'default', - }, - ), - ]), - ); - }); - test('orderBy assertions', () async { - // Can only order by the same field once. - expect(() { - firestore.collection('foo').orderBy('bar').orderBy('bar'); - }, throwsAssertionError); - // Cannot order by unsupported types. - expect(() { - firestore.collection('foo').orderBy(0); - }, throwsAssertionError); - // Parameters cannot be null. - expect(() { - firestore.collection('foo').orderBy(null); - }, throwsAssertionError); - expect(() { - firestore.collection('foo').orderBy('bar', descending: null); - }, throwsAssertionError); - - // Cannot order by document id when paginating with documents. - final DocumentReference documentReference = - firestore.document('foo/bar'); - final DocumentSnapshot snapshot = await documentReference.get(); - expect(() { - firestore - .collection('foo') - .startAfterDocument(snapshot) - .orderBy(FieldPath.documentId); - }, throwsAssertionError); - }); - test('document pagination FieldPath assertions', () async { - final DocumentReference documentReference = - firestore.document('foo/bar'); - final DocumentSnapshot snapshot = await documentReference.get(); - final Query query = - firestore.collection('foo').orderBy(FieldPath.documentId); - - expect(() { - query.startAfterDocument(snapshot); - }, throwsAssertionError); - expect(() { - query.startAtDocument(snapshot); - }, throwsAssertionError); - expect(() { - query.endAtDocument(snapshot); - }, throwsAssertionError); - expect(() { - query.endBeforeDocument(snapshot); - }, throwsAssertionError); - }); - }); - - group('FirestoreMessageCodec', () { - const MessageCodec codec = FirestoreMessageCodec(); - final DateTime testTime = DateTime(2015, 10, 30, 11, 16); - final Timestamp timestamp = Timestamp.fromDate(testTime); - test('should encode and decode simple messages', () { - _checkEncodeDecode(codec, testTime); - _checkEncodeDecode(codec, timestamp); - _checkEncodeDecode( - codec, const GeoPoint(37.421939, -122.083509)); - _checkEncodeDecode(codec, firestore.document('foo/bar')); - }); - test('should encode and decode composite message', () { - final List message = [ - testTime, - const GeoPoint(37.421939, -122.083509), - firestore.document('foo/bar'), - ]; - _checkEncodeDecode(codec, message); - }); - test('encode and decode blob', () { - final Uint8List bytes = Uint8List(4); - bytes[0] = 128; - final Blob message = Blob(bytes); - _checkEncodeDecode(codec, message); - }); - - test('encode and decode FieldValue', () { - _checkEncodeDecode(codec, FieldValue.arrayUnion([123])); - _checkEncodeDecode(codec, FieldValue.arrayRemove([123])); - _checkEncodeDecode(codec, FieldValue.delete()); - _checkEncodeDecode(codec, FieldValue.serverTimestamp()); - _checkEncodeDecode(codec, FieldValue.increment(1.0)); - _checkEncodeDecode(codec, FieldValue.increment(1)); - }); - - test('encode and decode FieldPath', () { - _checkEncodeDecode(codec, FieldPath.documentId); - }); - }); - - group('Timestamp', () { - test('is accurate for dates after epoch', () { - final DateTime date = DateTime.fromMillisecondsSinceEpoch(22501); - final Timestamp timestamp = Timestamp.fromDate(date); - - expect(timestamp.seconds, equals(22)); - expect(timestamp.nanoseconds, equals(501000000)); - }); - - test('is accurate for dates before epoch', () { - final DateTime date = DateTime.fromMillisecondsSinceEpoch(-1250); - final Timestamp timestamp = Timestamp.fromDate(date); - - expect(timestamp.seconds, equals(-2)); - expect(timestamp.nanoseconds, equals(750000000)); - }); - - test('creates equivalent timestamps regardless of factory', () { - const int kMilliseconds = 22501; - const int kMicroseconds = 22501000; - final DateTime date = - DateTime.fromMicrosecondsSinceEpoch(kMicroseconds); - - final Timestamp timestamp = Timestamp(22, 501000000); - final Timestamp milliTimestamp = - Timestamp.fromMillisecondsSinceEpoch(kMilliseconds); - final Timestamp microTimestamp = - Timestamp.fromMicrosecondsSinceEpoch(kMicroseconds); - final Timestamp dateTimestamp = Timestamp.fromDate(date); - - expect(timestamp, equals(milliTimestamp)); - expect(milliTimestamp, equals(microTimestamp)); - expect(microTimestamp, equals(dateTimestamp)); - }); - - test('correctly compares timestamps', () { - final Timestamp alpha = Timestamp.fromDate(DateTime(2017, 5, 11)); - final Timestamp beta1 = Timestamp.fromDate(DateTime(2018, 2, 19)); - final Timestamp beta2 = Timestamp.fromDate(DateTime(2018, 4, 2)); - final Timestamp beta3 = Timestamp.fromDate(DateTime(2018, 4, 20)); - final Timestamp preview = Timestamp.fromDate(DateTime(2018, 6, 20)); - final List inOrder = [ - alpha, - beta1, - beta2, - beta3, - preview - ]; - - final List timestamps = [ - beta2, - beta3, - alpha, - preview, - beta1 - ]; - timestamps.sort(); - expect(_deepEqualsList(timestamps, inOrder), isTrue); - }); - - test('rejects dates outside RFC 3339 range', () { - final List invalidDates = [ - DateTime.fromMillisecondsSinceEpoch(-70000000000000), - DateTime.fromMillisecondsSinceEpoch(300000000000000), - ]; - - invalidDates.forEach((DateTime date) { - expect(() => Timestamp.fromDate(date), throwsArgumentError); - }); - }); - }); - - group('WriteBatch', () { - test('set', () async { - final WriteBatch batch = firestore.batch(); - batch.setData( - collectionReference.document('bar'), - {'bazKey': 'quxValue'}, - ); - await batch.commit(); - expect( - log, - [ - isMethodCall('WriteBatch#create', arguments: { - 'app': app.name, - }), - isMethodCall( - 'WriteBatch#setData', - arguments: { - 'app': app.name, - 'handle': 1, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - 'options': {'merge': false}, - }, - ), - isMethodCall( - 'WriteBatch#commit', - arguments: { - 'handle': 1, - }, - ), - ], - ); - }); - test('merge set', () async { - final WriteBatch batch = firestore.batch(); - batch.setData( - collectionReference.document('bar'), - {'bazKey': 'quxValue'}, - merge: true, - ); - await batch.commit(); - expect( - log, - [ - isMethodCall('WriteBatch#create', arguments: { - 'app': app.name, - }), - isMethodCall('WriteBatch#setData', arguments: { - 'app': app.name, - 'handle': 1, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - 'options': {'merge': true}, - }), - isMethodCall( - 'WriteBatch#commit', - arguments: { - 'handle': 1, - }, - ), - ], - ); - }); - test('update', () async { - final WriteBatch batch = firestore.batch(); - batch.updateData( - collectionReference.document('bar'), - {'bazKey': 'quxValue'}, - ); - await batch.commit(); - expect( - log, - [ - isMethodCall( - 'WriteBatch#create', - arguments: { - 'app': app.name, - }, - ), - isMethodCall( - 'WriteBatch#updateData', - arguments: { - 'app': app.name, - 'handle': 1, - 'path': 'foo/bar', - 'data': {'bazKey': 'quxValue'}, - }, - ), - isMethodCall( - 'WriteBatch#commit', - arguments: { - 'handle': 1, - }, - ), - ], - ); - }); - test('delete', () async { - final WriteBatch batch = firestore.batch(); - batch.delete(collectionReference.document('bar')); - await batch.commit(); - expect( - log, - [ - isMethodCall( - 'WriteBatch#create', - arguments: { - 'app': app.name, - }, - ), - isMethodCall( - 'WriteBatch#delete', - arguments: { - 'app': app.name, - 'handle': 1, - 'path': 'foo/bar', - }, - ), - isMethodCall( - 'WriteBatch#commit', - arguments: { - 'handle': 1, - }, - ), - ], - ); - }); - }); - }); -} - -void _checkEncodeDecode(MessageCodec codec, T message) { - final ByteData encoded = codec.encodeMessage(message); - final T decoded = codec.decodeMessage(encoded); - if (message == null) { - expect(encoded, isNull); - expect(decoded, isNull); - } else { - expect(_deepEquals(message, decoded), isTrue); - final ByteData encodedAgain = codec.encodeMessage(decoded); - expect( - encodedAgain.buffer.asUint8List(), - orderedEquals(encoded.buffer.asUint8List()), - ); - } -} - -bool _deepEquals(dynamic valueA, dynamic valueB) { - if (valueA is TypedData) - return valueB is TypedData && _deepEqualsTypedData(valueA, valueB); - if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); - if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); - if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; - if (valueA is FieldValue) { - return valueB is FieldValue && _deepEqualsFieldValue(valueA, valueB); - } - if (valueA is FieldPath) - return valueB is FieldPath && valueA.type == valueB.type; - return valueA == valueB; -} - -bool _deepEqualsTypedData(TypedData valueA, TypedData valueB) { - if (valueA is ByteData) { - return valueB is ByteData && - _deepEqualsList( - valueA.buffer.asUint8List(), valueB.buffer.asUint8List()); - } - if (valueA is Uint8List) - return valueB is Uint8List && _deepEqualsList(valueA, valueB); - if (valueA is Int32List) - return valueB is Int32List && _deepEqualsList(valueA, valueB); - if (valueA is Int64List) - return valueB is Int64List && _deepEqualsList(valueA, valueB); - if (valueA is Float64List) - return valueB is Float64List && _deepEqualsList(valueA, valueB); - throw 'Unexpected typed data: $valueA'; -} - -bool _deepEqualsList(List valueA, List valueB) { - if (valueA.length != valueB.length) return false; - for (int i = 0; i < valueA.length; i++) { - if (!_deepEquals(valueA[i], valueB[i])) return false; - } - return true; -} - -bool _deepEqualsMap( - Map valueA, Map valueB) { - if (valueA.length != valueB.length) return false; - for (final dynamic key in valueA.keys) { - if (!valueB.containsKey(key) || !_deepEquals(valueA[key], valueB[key])) - return false; - } - return true; -} - -bool _deepEqualsFieldValue(FieldValue valueA, FieldValue valueB) { - if (valueA.type != valueB.type) return false; - if (valueA.value == null) return valueB.value == null; - if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); - if (valueA.value is Map) return _deepEqualsMap(valueA.value, valueB.value); - return valueA.value == valueB.value; -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 6019f4dbeeb7..a32caeffacc7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -42,10 +42,10 @@ abstract class FirestorePlatform { final FirebaseApp app; - FirestorePlatform._(this.app); + FirestorePlatform({FirebaseApp app}): app = app ?? FirebaseApp.instance; - factory FirestorePlatform({FirebaseApp app}) { - FirestorePlatform.instance = FirestorePlatform.instance._withApp(app); + factory FirestorePlatform.withApp({FirebaseApp app}) { + FirestorePlatform.instance = FirestorePlatform.instance.withApp(app); return FirestorePlatform.instance; } /// Only mock implementations should set this to `true`. @@ -72,7 +72,7 @@ abstract class FirestorePlatform { _instance = instance; } - FirestorePlatform _withApp(FirebaseApp app) { + FirestorePlatform withApp(FirebaseApp app) { throw UnimplementedError("_withApp() not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index e97244bd7b93..293927f9a89d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -89,7 +89,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { final String appName = utf8.decoder.convert(buffer.getUint8List(appNameLength)); final FirebaseApp app = FirebaseApp(name: appName); - final FirestorePlatform firestore = FirestorePlatform(app: app); + final FirestorePlatform firestore = FirestorePlatform.withApp(app: app); final int pathLength = readSize(buffer); final String path = utf8.decoder.convert(buffer.getUint8List(pathLength)); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 1213c2c6055a..bb9c4ec361cb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -10,7 +10,7 @@ part of cloud_firestore_platform_interface; class MethodChannelFirestore extends FirestorePlatform { MethodChannelFirestore({FirebaseApp app}) - : super._(app ?? FirebaseApp.instance) { + : super(app: app ?? FirebaseApp.instance) { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { @@ -60,7 +60,7 @@ class MethodChannelFirestore extends FirestorePlatform { @override - FirestorePlatform _withApp(FirebaseApp app) => + FirestorePlatform withApp(FirebaseApp app) => MethodChannelFirestore(app: app); @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index d9fb38702951..5f85b553a220 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -3,35 +3,39 @@ import 'package:cloud_firestore_web/collection_reference_web.dart'; import 'package:cloud_firestore_web/document_reference_web.dart'; import 'package:cloud_firestore_web/query_web.dart'; import 'package:firebase/firebase.dart' as firebase; -import 'package:firebase/firestore.dart' show Settings; -import 'package:flutter/cupertino.dart'; +import 'package:firebase/firestore.dart' show Firestore, Settings; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; class FirestoreWeb extends FirestorePlatform { + + final Firestore webFirestore; + static void registerWith(Registrar registrar) { FirestorePlatform.instance = FirestoreWeb(); + } - FirestoreWeb() : super(); + FirestoreWeb({FirebaseApp app}): webFirestore = firebase.firestore(firebase.app((app ?? FirebaseApp.instance).name)),super(app: app ?? FirebaseApp.instance); - final app = firebase.firestore(); + @override + FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); @override CollectionReference collection(String path) { - - return CollectionReferenceWeb(this, app, path.split('/')); + return CollectionReferenceWeb( + this, webFirestore, path.split('/')); } - @override Query collectionGroup(String path) { return QueryWeb(this, path, - isCollectionGroup: true, webQuery: app.collectionGroup(path)); + isCollectionGroup: true, webQuery: webFirestore.collectionGroup(path)); } @override DocumentReference document(String path) => - DocumentReferenceWeb(app, this, path.split('/')); + DocumentReferenceWeb(webFirestore, this, path.split('/')); @override WriteBatch batch() => WriteBatch(this); @@ -39,7 +43,7 @@ class FirestoreWeb extends FirestorePlatform { @override Future enablePersistence(bool enable) async { if (enable) { - await app.enablePersistence(); + await webFirestore.enablePersistence(); } } @@ -50,10 +54,8 @@ class FirestoreWeb extends FirestorePlatform { bool sslEnabled, int cacheSizeBytes}) async { return Future.sync(() { - - app.settings( - Settings(ssl: sslEnabled, cacheSizeBytes: cacheSizeBytes, host: host)); - + webFirestore.settings(Settings( + ssl: sslEnabled, cacheSizeBytes: cacheSizeBytes, host: host)); }); } @@ -62,5 +64,5 @@ class FirestoreWeb extends FirestorePlatform { {Duration timeout = const Duration(seconds: 5)}) async {} @override - String appName() => firebase.app().name; + String appName() => app.name; } diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index 361702885dc3..ce215db962d4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: firebase: ^7.0.0 http_parser: ^3.1.3 meta: ^1.1.7 + firebase_core: ^0.4.3+1 cloud_firestore_platform_interface: path: ../cloud_firestore_platform_interface js: ^0.6.1 @@ -28,7 +29,6 @@ dev_dependencies: cloud_firestore: path: ../cloud_firestore firebase_core_platform_interface: ^1.0.0 - firebase_core_web: ^0.1.1 environment: sdk: ">=2.1.0 <3.0.0" From 3e24ca262fae9e4385aa6667dd3d7fafba0bce73 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 11:51:27 +0000 Subject: [PATCH 017/144] added transaction implementation --- .../cloud_firestore/lib/cloud_firestore.dart | 5 +- .../cloud_firestore/lib/src/firestore.dart | 17 +++--- .../cloud_firestore/lib/src/transaction.dart | 58 +++++-------------- .../lib/src/transaction.dart | 3 +- .../src/transaction_platform_interface.dart | 1 - .../lib/collection_reference_web.dart | 5 +- .../lib/document_reference_web.dart | 19 +++--- .../lib/firestore_web.dart | 20 +++++-- .../cloud_firestore_web/lib/query_web.dart | 4 +- .../lib/transaction_web.dart | 49 ++++++++++++++++ 10 files changed, 104 insertions(+), 77 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 883ef34ccb3d..084a0f20339d 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -16,10 +16,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; - -import 'src/utils/auto_id_generator.dart'; -export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; - +export 'package:cloud_firestore_web/firestore_web.dart'; part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 5a73556f4736..8fa7b332e2e1 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -7,16 +7,16 @@ part of cloud_firestore; /// The entry point for accessing a Firestore. /// /// You can get an instance by calling [Firestore.instance]. -class Firestore { - +class Firestore { final platform.FirestorePlatform _delegate; Firestore({FirebaseApp app, platform.FirestorePlatform delegate}) - : _delegate = delegate ?? platform.FirestorePlatform.instance; + : _delegate = delegate ?? platform.FirestorePlatform.instance; static MethodChannel get channel => platform.MethodChannelFirestore.channel; - static Firestore get instance => Firestore(delegate: platform.FirestorePlatform.instance); + static Firestore get instance => + Firestore(delegate: platform.FirestorePlatform.instance); String appName() => _delegate.appName(); @@ -36,9 +36,12 @@ class Firestore { Future enablePersistence(bool enable) => _delegate.enablePersistence(enable); - Future> runTransaction(transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) => - _delegate.runTransaction(transactionHandler, timeout: timeout); + Future> runTransaction( + TransactionHandler transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) { + return _delegate.runTransaction((platformTransaction) => + transactionHandler(Transaction._(platformTransaction))); + } Future settings( {bool persistenceEnabled, diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 40c4fc15913f..f7cbe1634824 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -7,25 +7,16 @@ part of cloud_firestore; typedef Future TransactionHandler(Transaction transaction); class Transaction { - @visibleForTesting - Transaction(int transactionId) - : _delegate = platform.Transaction( - transactionId, platform.FirestorePlatform.instance); + + Transaction._(this._delegate); platform.Transaction _delegate; - List> _pendingResults = >[]; Future _finish() => _delegate.finish(); /// Reads the document referenced by the provided DocumentReference. - Future get(DocumentReference documentReference) { - final Future result = _get(documentReference); - _pendingResults.add(result); - return result; - } - - Future _get(DocumentReference documentReference) async { + Future get(DocumentReference documentReference) async { final result = await _delegate.get(platform.MethodChannelDocumentReference( platform.FirestorePlatform.instance, documentReference.path.split("/"))); @@ -41,16 +32,11 @@ class Transaction { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future delete(DocumentReference documentReference) { - final Future result = _delete(documentReference); - _pendingResults.add(result); - return result; + return _delegate.delete(platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/"))); } - Future _delete(DocumentReference documentReference) async => - _delegate.delete(platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/"))); - /// Updates fields in the document referred to by [documentReference]. /// The update will fail if applied to a document that does not exist. /// @@ -58,19 +44,13 @@ class Transaction { /// when the transaction handler completes. Future update( DocumentReference documentReference, Map data) async { - final Future result = _update(documentReference, data); - _pendingResults.add(result); - return result; + return _delegate.update( + platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/")), + data); } - Future _update(DocumentReference documentReference, - Map data) async => - _delegate.update( - platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/")), - data); - /// Writes to the document referred to by the provided [DocumentReference]. /// If the document does not exist yet, it will be created. If you pass /// SetOptions, the provided data can be merged into the existing document. @@ -79,16 +59,10 @@ class Transaction { /// when the transaction handler completes. Future set( DocumentReference documentReference, Map data) { - final Future result = _set(documentReference, data); - _pendingResults.add(result); - return result; + return _delegate.set( + platform.MethodChannelDocumentReference( + platform.FirestorePlatform.instance, + documentReference.path.split("/")), + data); } - - Future _set(DocumentReference documentReference, - Map data) async => - _delegate.set( - platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/")), - data); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index b59d3c459b0a..4d78040ff37e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -7,7 +7,8 @@ part of cloud_firestore_platform_interface; class Transaction extends TransactionPlatform { @visibleForTesting Transaction(int transactionId, FirestorePlatform firestore) : super(transactionId, firestore); - + + Future finish() => Future.wait(_pendingResults); @override Future _get(DocumentReference documentReference) async { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart index f2cd2668d92b..42e4f272580e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -13,7 +13,6 @@ abstract class TransactionPlatform { int _transactionId; FirestorePlatform firestore; List> _pendingResults = >[]; - Future finish() => Future.wait(_pendingResults); /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReference documentReference) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 2eb63481eb65..41cc1e8bb165 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -1,7 +1,4 @@ -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/document_reference_web.dart'; -import 'package:cloud_firestore_web/query_web.dart'; -import 'package:firebase/firestore.dart' as web; +part of cloud_firestore_web; class CollectionReferenceWeb implements CollectionReference { final web.Firestore webFirestore; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index a73e77acaf62..0eb8ff388776 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -1,35 +1,34 @@ -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; +part of cloud_firestore_web; class DocumentReferenceWeb extends DocumentReference { - final web.Firestore firestoreWeb; + final web.Firestore firestoreWeb; + final web.DocumentReference delegate; DocumentReferenceWeb(this.firestoreWeb,FirestorePlatform firestore, List pathComponents) - : super(firestore, pathComponents); + : delegate = firestoreWeb.doc(pathComponents.join("/")),super(firestore, pathComponents); @override Future setData(Map data, {bool merge = false}) { - return firestoreWeb.doc(path).set(data, web.SetOptions(merge: merge)); + return delegate.set(data, web.SetOptions(merge: merge)); } @override Future updateData(Map data) { - return firestoreWeb.doc(path).update(data: data); + return delegate.update(data: data); } @override Future get({Source source = Source.serverAndCache}) async { - return _fromWeb(await firestoreWeb.doc(path).get()); + return _fromWeb(await delegate.get()); } @override Future delete() { - return firestoreWeb.doc(path).delete(); + return delegate.delete(); } @override Stream snapshots({bool includeMetadataChanges = false}) { - return firestoreWeb - .doc(path) + return delegate .onSnapshot .map((web.DocumentSnapshot webSnapshot) => _fromWeb(webSnapshot)); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 5f85b553a220..ad7317e23e31 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -1,11 +1,16 @@ +library cloud_firestore_web; + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/collection_reference_web.dart'; -import 'package:cloud_firestore_web/document_reference_web.dart'; -import 'package:cloud_firestore_web/query_web.dart'; import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; +import 'package:firebase/firestore.dart' as web; + +part 'collection_reference_web.dart'; +part 'document_reference_web.dart'; +part 'query_web.dart'; +part 'transaction_web.dart'; class FirestoreWeb extends FirestorePlatform { @@ -60,9 +65,14 @@ class FirestoreWeb extends FirestorePlatform { } @override - Future> runTransaction(transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) async {} + Future> runTransaction(TransactionHandler transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) { + return webFirestore.runTransaction((transaction) { + transactionHandler(TransactionWeb._(transaction, this)); + }); + } @override String appName() => app.name; + } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 86758d24fd60..601ec3f32976 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,6 +1,4 @@ -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:flutter/cupertino.dart'; +part of cloud_firestore_web; class QueryWeb implements Query { final web.CollectionReference webCollection; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart new file mode 100644 index 000000000000..27590249ec19 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -0,0 +1,49 @@ +part of cloud_firestore_web; + +class TransactionWeb implements Transaction { + final web.Transaction _webTransaction; + @override + FirestorePlatform firestore; + + TransactionWeb._(this._webTransaction, this.firestore); + + @override + Future delete(DocumentReference documentReference) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction.delete((documentReference as DocumentReferenceWeb).delegate); + } + + @override + Future get(DocumentReference documentReference) async { + assert(documentReference is DocumentReferenceWeb); + final webSnapshot = await _webTransaction.get((documentReference as DocumentReferenceWeb).delegate); + return _fromWeb(webSnapshot); + } + + @override + Future set(DocumentReference documentReference, Map data) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction.set((documentReference as DocumentReferenceWeb).delegate, data); + } + + @override + Future update(DocumentReference documentReference, Map data) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction.update((documentReference as DocumentReferenceWeb).delegate, data: data); + } + + DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + this.firestore); + + @override + Future finish() { + return Future.value(); + } + +} \ No newline at end of file From 76037e7c62d4617479eecc3efc67de3866c508e9 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 11:56:28 +0000 Subject: [PATCH 018/144] updated readmes --- .../cloud_firestore/pubspec.yaml | 2 +- .../README.md | 32 +++++++++++++------ .../cloud_firestore_web/README.md | 16 +++++----- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index 4e0019ca6f43..d7565e12b12b 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Cloud Firestore, a cloud-hosted, noSQL database with live synchronization and offline support on Android and iOS. homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore -version: 0.13.0+1 +version: 0.13.1 flutter: plugin: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/README.md b/packages/cloud_firestore/cloud_firestore_platform_interface/README.md index 9e6d2ecdba2f..77d9bdd7d10f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/README.md +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/README.md @@ -1,14 +1,26 @@ -# cloud_firestore_platfrom_interface +# cloud_firestore_platform_interface -A new Flutter package project. +A common platform interface for the [`cloud_firestore`][1] plugin. -## Getting Started +This interface allows platform-specific implementations of the `cloud_firestore` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. -This project is a starting point for a Dart -[package](https://flutter.dev/developing-packages/), -a library module containing code that can be shared easily across -multiple Flutter or Dart projects. +# Usage -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +To implement a new platform-specific implementation of `cloud_firebase`, extend +[`FirestorePlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`FirestorePlatform` by calling +`FirestorePlatform.instance = MyFirestore()`. + +# Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../cloud_firestore +[2]: lib/cloud_firestore_platform_interface.dart \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/README.md b/packages/cloud_firestore/cloud_firestore_web/README.md index f01d4b00f981..1788e7539e3c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/README.md +++ b/packages/cloud_firestore/cloud_firestore_web/README.md @@ -1,17 +1,17 @@ -# firebase_auth_web +# cloud_firestore_web -The web implementation of [`firebase_core`][1]. +The web implementation of [`cloud_firestore`][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_auth` +dependency in your `pubspec.yaml` alongside the base `cloud_firestore` plugin. _(This is only temporary: in the future we hope to make this package -an "endorsed" implementation of `firebase_auth`, so it will automatically +an "endorsed" implementation of `cloud_firestore`, so it will automatically be included in your app when you run your Flutter app on the web.)_ Add this to your `pubspec.yaml`: @@ -20,8 +20,8 @@ Add this to your `pubspec.yaml`: ... dependencies: ... - firebase_auth: ^0.15.1 - firebase_auth_web: ^0.1.0 + cloud_firestore: ^0.13.1 + firebase_auth_web: ^0.0.1 ... ``` @@ -37,7 +37,7 @@ In your app directory, edit `web/index.html` to add the line: ... - + @@ -48,5 +48,5 @@ In your app directory, edit `web/index.html` to add the line: Once you have added the `firebase_auth_web` dependency to your pubspec, you can use `package:firebase_auth` as normal. -[1]: ../firebase_auth +[1]: ../cloud_firestore [2]: https://github.com/dart-lang/sdk/issues/33979 From ffb12cd2b917c58bb1e9ea737e2f41f1ac8abf15 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 12:08:51 +0000 Subject: [PATCH 019/144] fixed copy typo on readme --- .../cloud_firestore_platform_interface/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml index a5643ce810c7..3357bbe781d8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml @@ -1,5 +1,5 @@ name: cloud_firestore_platform_interface -description: A common platform interface for the firebase_auth plugin. +description: A common platform interface for the cloud_firestore plugin. version: 0.0.1 homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_platform_interface From c30f1f7fcccba9443788bf067c388c083a98846b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Tue, 17 Dec 2019 20:09:31 +0000 Subject: [PATCH 020/144] - Added change log - use any as versions --- .../cloud_firestore/CHANGELOG.md | 4 +++ .../cloud_firestore/pubspec.yaml | 6 ++--- .../CHANGELOG.md | 4 +-- .../LICENSE | 27 ++++++++++++++++++- .../cloud_firestore_web/CHANGELOG.md | 23 ++-------------- .../cloud_firestore_web/pubspec.yaml | 6 ++--- 6 files changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore/CHANGELOG.md index da2dd7443e15..9a3cb32d9926 100644 --- a/packages/cloud_firestore/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.1 + +* Added support for Flutter Web + ## 0.13.0+1 * Remove the deprecated `author:` field from pubspec.yaml diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index d7565e12b12b..8987c829c6b5 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -22,10 +22,8 @@ dependencies: meta: "^1.0.5" collection: "^1.14.3" firebase_core: "^0.4.0" - cloud_firestore_platform_interface: - path: ../cloud_firestore_platform_interface - cloud_firestore_web: - path: ../cloud_firestore_web + cloud_firestore_platform_interface: any + cloud_firestore_web: any dev_dependencies: flutter_test: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md index ac071598e5d4..b60fe9614434 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md @@ -1,3 +1,3 @@ -## [0.0.1] - TODO: Add release date. +## [0.0.1] -* TODO: Describe initial release. +* Created Platform Interface diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE b/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE index ba75c69f7f21..5b8ff6261110 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/LICENSE @@ -1 +1,26 @@ -TODO: Add your license here. +Copyright 2017, the Chromium project 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/cloud_firestore/cloud_firestore_web/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md index 12ad56ba3fd6..8454a65ff176 100644 --- a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md @@ -1,22 +1,3 @@ -## 0.1.1+1 +## 0.0.1 -* Add an android/ folder with no-op implementation to workaround https://github.com/flutter/flutter/issues/46898 - -## 0.1.1 - -* Require Flutter SDK version 1.12.13+hotfix.4 or later. -* Add fake podspec so we don't break compilation on iOS. -* Fix homepage. - -## 0.1.0+2 - -* Remove the deprecated `author:` field from pubspec.yaml. -* Bump the minimum Flutter version to 1.10.0. - -## 0.1.0+1 - -* Fixed serialization error for creationTime and lastSignInTime being RFC 1123. - -## 0.1.0 - -* Initial open-source release. +- Initial release \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index ce215db962d4..334f819c27df 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -19,15 +19,13 @@ dependencies: http_parser: ^3.1.3 meta: ^1.1.7 firebase_core: ^0.4.3+1 - cloud_firestore_platform_interface: - path: ../cloud_firestore_platform_interface + cloud_firestore_platform_interface: any js: ^0.6.1 dev_dependencies: flutter_test: sdk: flutter - cloud_firestore: - path: ../cloud_firestore + cloud_firestore: any firebase_core_platform_interface: ^1.0.0 environment: From 65984ff27659af664562bbe2b16b9ffd17554136 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 12:39:11 +0000 Subject: [PATCH 021/144] Added support for field value Created FieldValueFactory to provide platform-specific FieldValue instances --- .gitignore | 2 + .../example/android/gradle.properties | 3 +- .../lib/generated_plugin_registrant.dart | 15 ++++ .../cloud_firestore/example/lib/main.dart | 1 + .../cloud_firestore/example/web/index.html | 26 +++++++ .../cloud_firestore/lib/src/field_value.dart | 45 +++++------- .../lib/src/firestore_message_codec.dart | 16 ++--- .../cloud_firestore/pubspec.yaml | 6 +- .../cloud_firestore_platform_interface.dart | 4 +- .../lib/src/field_value.dart | 68 ------------------- .../lib/src/firestore_message_codec.dart | 12 ++-- .../method_channel_field_value_factory.dart | 33 +++++++++ .../src/platform_interface/field_value.dart | 28 ++++++++ .../field_value_factory.dart | 49 +++++++++++++ .../method_channel_cloud_firestore_test.dart | 12 ++-- .../lib/collection_reference_web.dart | 2 +- .../lib/document_reference_web.dart | 48 +++++++------ .../lib/field_value_factory_web.dart | 35 ++++++++++ .../lib/field_value_web.dart | 28 ++++++++ .../lib/firestore_web.dart | 18 +++-- .../cloud_firestore_web/pubspec.yaml | 4 +- 21 files changed, 299 insertions(+), 156 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart create mode 100644 packages/cloud_firestore/cloud_firestore/example/web/index.html delete mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart diff --git a/.gitignore b/.gitignore index ccb0eeb34605..38665e212f96 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ build/ .project .classpath .settings + +.flutter-plugins-dependencies diff --git a/packages/cloud_firestore/cloud_firestore/example/android/gradle.properties b/packages/cloud_firestore/cloud_firestore/example/android/gradle.properties index 4d3226abc21b..a6738207fd15 100755 --- a/packages/cloud_firestore/cloud_firestore/example/android/gradle.properties +++ b/packages/cloud_firestore/cloud_firestore/example/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true +android.enableR8=true diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart b/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart new file mode 100644 index 000000000000..dc9465bdf947 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// +import 'dart:ui'; + +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:firebase_core_web/firebase_core_web.dart'; + +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +void registerPlugins(PluginRegistry registry) { + FirestoreWeb.registerWith(registry.registrarFor(FirestoreWeb)); + FirebaseCoreWeb.registerWith(registry.registrarFor(FirebaseCoreWeb)); + registry.registerMessageHandler(); +} diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index ca656fbc61fd..9b1954d0a0f8 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -9,6 +9,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; Future main() async { + WidgetsFlutterBinding.ensureInitialized(); final FirebaseApp app = await FirebaseApp.configure( name: 'test', options: const FirebaseOptions( diff --git a/packages/cloud_firestore/cloud_firestore/example/web/index.html b/packages/cloud_firestore/cloud_firestore/example/web/index.html new file mode 100644 index 000000000000..07f2b9039607 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/example/web/index.html @@ -0,0 +1,26 @@ + + + + + example + + + + + + + + diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 4ab12b0411f3..f7ba79de1bfb 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -4,26 +4,21 @@ part of cloud_firestore; -@visibleForTesting -enum FieldValueType { - arrayUnion, - arrayRemove, - delete, - serverTimestamp, - incrementDouble, - incrementInteger, -} - /// Sentinel values that can be used when writing document fields with set() or /// update(). -class FieldValue { - FieldValue._(this.type, this.value); +class FieldValue implements platform.FieldValueInterface{ + platform.FieldValueInterface _delegate; + + FieldValue._(this._delegate); + + @override + platform.FieldValueInterface get instance => _delegate; @visibleForTesting - final FieldValueType type; + platform.FieldValueType get type => _delegate.type; @visibleForTesting - final dynamic value; + dynamic get value => _delegate.value; /// Returns a special value that tells the server to union the given elements /// with any array value that already exists on the server. @@ -33,7 +28,7 @@ class FieldValue { /// will be overwritten with an array containing exactly the specified /// elements. static FieldValue arrayUnion(List elements) => - FieldValue._(FieldValueType.arrayUnion, elements); + FieldValue._(platform.FieldValueFactory.instance.arrayUnion(elements)); /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -42,27 +37,19 @@ class FieldValue { /// If the field being modified is not already an array it will be overwritten /// with an empty array. static FieldValue arrayRemove(List elements) => - FieldValue._(FieldValueType.arrayRemove, elements); + FieldValue._(platform.FieldValueFactory.instance.arrayRemove(elements)); /// Returns a sentinel for use with update() to mark a field for deletion. - static FieldValue delete() => FieldValue._(FieldValueType.delete, null); + static FieldValue delete() => + FieldValue._(platform.FieldValueFactory.instance.delete()); /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. static FieldValue serverTimestamp() => - FieldValue._(FieldValueType.serverTimestamp, null); + FieldValue._(platform.FieldValueFactory.instance.serverTimestamp()); /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - static FieldValue increment(num value) { - // It is a compile-time error for any type other than int or double to - // attempt to extend or implement num. - assert(value is int || value is double); - if (value is double) { - return FieldValue._(FieldValueType.incrementDouble, value); - } else if (value is int) { - return FieldValue._(FieldValueType.incrementInteger, value); - } - return null; - } + static FieldValue increment(num value) => + FieldValue._(platform.FieldValueFactory.instance.increment(value)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart index 40698f1a8b78..ebcb923dc4e6 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart @@ -21,14 +21,14 @@ class FirestoreMessageCodec extends StandardMessageCodec { static const int _kIncrementInteger = 138; static const int _kDocumentId = 139; - static const Map _kFieldValueCodes = - { - FieldValueType.arrayUnion: _kArrayUnion, - FieldValueType.arrayRemove: _kArrayRemove, - FieldValueType.delete: _kDelete, - FieldValueType.serverTimestamp: _kServerTimestamp, - FieldValueType.incrementDouble: _kIncrementDouble, - FieldValueType.incrementInteger: _kIncrementInteger, + static const Map _kFieldValueCodes = + { + platform.FieldValueType.arrayUnion: _kArrayUnion, + platform.FieldValueType.arrayRemove: _kArrayRemove, + platform.FieldValueType.delete: _kDelete, + platform.FieldValueType.serverTimestamp: _kServerTimestamp, + platform.FieldValueType.incrementDouble: _kIncrementDouble, + platform.FieldValueType.incrementInteger: _kIncrementInteger, }; static const Map<_FieldPathType, int> _kFieldPathCodes = diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index 8987c829c6b5..d7565e12b12b 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -22,8 +22,10 @@ dependencies: meta: "^1.0.5" collection: "^1.14.3" firebase_core: "^0.4.0" - cloud_firestore_platform_interface: any - cloud_firestore_web: any + cloud_firestore_platform_interface: + path: ../cloud_firestore_platform_interface + cloud_firestore_web: + path: ../cloud_firestore_web dev_dependencies: flutter_test: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index a32caeffacc7..26ff14254559 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -15,6 +15,8 @@ import 'package:meta/meta.dart' show required, visibleForTesting; part 'src/method_channel_firestore.dart'; part 'src/blob.dart'; part 'src/utils/auto_id_generator.dart'; +part 'src/method_channel_field_value_factory.dart'; +part 'src/platform_interface/field_value_factory.dart'; part 'src/platform_interface/collection_reference.dart'; part 'src/method_channel_collection_reference.dart'; part 'src/method_channel_document_change.dart'; @@ -23,7 +25,7 @@ part 'src/method_channel_document_reference.dart'; part 'src/platform_interface/document_reference_interface.dart'; part 'src/document_snapshot.dart'; part 'src/field_path.dart'; -part 'src/field_value.dart'; +part 'src/platform_interface/field_value.dart'; part 'src/firestore_message_codec.dart'; part 'src/geo_point.dart'; part 'src/method_channel_query.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart deleted file mode 100644 index 534dfe49c43f..000000000000 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_value.dart +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; - -@visibleForTesting -enum FieldValueType { - arrayUnion, - arrayRemove, - delete, - serverTimestamp, - incrementDouble, - incrementInteger, -} - -/// Sentinel values that can be used when writing document fields with set() or -/// update(). -class FieldValue { - FieldValue._(this.type, this.value); - - @visibleForTesting - final FieldValueType type; - - @visibleForTesting - final dynamic value; - - /// Returns a special value that tells the server to union the given elements - /// with any array value that already exists on the server. - /// - /// Each specified element that doesn't already exist in the array will be - /// added to the end. If the field being modified is not already an array it - /// will be overwritten with an array containing exactly the specified - /// elements. - static FieldValue arrayUnion(List elements) => - FieldValue._(FieldValueType.arrayUnion, elements); - - /// Returns a special value that tells the server to remove the given - /// elements from any array value that already exists on the server. - /// - /// All instances of each element specified will be removed from the array. - /// If the field being modified is not already an array it will be overwritten - /// with an empty array. - static FieldValue arrayRemove(List elements) => - FieldValue._(FieldValueType.arrayRemove, elements); - - /// Returns a sentinel for use with update() to mark a field for deletion. - static FieldValue delete() => FieldValue._(FieldValueType.delete, null); - - /// Returns a sentinel for use with set() or update() to include a - /// server-generated timestamp in the written data. - static FieldValue serverTimestamp() => - FieldValue._(FieldValueType.serverTimestamp, null); - - /// Returns a special value for use with set() or update() that tells the - /// server to increment the field’s current value by the given value. - static FieldValue increment(num value) { - // It is a compile-time error for any type other than int or double to - // attempt to extend or implement num. - assert(value is int || value is double); - if (value is double) { - return FieldValue._(FieldValueType.incrementDouble, value); - } else if (value is int) { - return FieldValue._(FieldValueType.incrementInteger, value); - } - return null; - } -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index 293927f9a89d..a29753e18985 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -100,20 +100,20 @@ class FirestoreMessageCodec extends StandardMessageCodec { return Blob(bytes); case _kArrayUnion: final List value = readValue(buffer); - return FieldValue.arrayUnion(value); + return FieldValueFactory._instance.arrayUnion(value); case _kArrayRemove: final List value = readValue(buffer); - return FieldValue.arrayRemove(value); + return FieldValueFactory._instance.arrayRemove(value); case _kDelete: - return FieldValue.delete(); + return FieldValueFactory._instance.delete(); case _kServerTimestamp: - return FieldValue.serverTimestamp(); + return FieldValueFactory._instance.serverTimestamp(); case _kIncrementDouble: final double value = readValue(buffer); - return FieldValue.increment(value); + return FieldValueFactory._instance.increment(value); case _kIncrementInteger: final int value = readValue(buffer); - return FieldValue.increment(value); + return FieldValueFactory._instance.increment(value); case _kDocumentId: return FieldPath.documentId; default: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart new file mode 100644 index 000000000000..376af0270fa0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart @@ -0,0 +1,33 @@ +part of cloud_firestore_platform_interface; + +class MethodChannelFieldValueFactory implements FieldValueFactory { + @override + FieldValue arrayRemove(List elements) => + FieldValue._(FieldValueType.arrayRemove, elements); + + @override + FieldValue arrayUnion(List elements) => + FieldValue._(FieldValueType.arrayUnion, elements); + + @override + FieldValue delete() => FieldValue._(FieldValueType.delete, null); + + + @override + FieldValue increment(num value) { + // It is a compile-time error for any type other than int or double to + // attempt to extend or implement num. + assert(value is int || value is double); + if (value is double) { + return FieldValue._(FieldValueType.incrementDouble, value); + } else if (value is int) { + return FieldValue._(FieldValueType.incrementInteger, value); + } + return null; + } + + @override + FieldValue serverTimestamp() => + FieldValue._(FieldValueType.serverTimestamp, null); + +} \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart new file mode 100644 index 000000000000..4237f3ba6df9 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -0,0 +1,28 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of cloud_firestore_platform_interface; + +/// Sentinel values that can be used when writing document fields with set() or +/// update(). + +abstract class FieldValueInterface { + + FieldValueInterface get instance; + + FieldValueType get type; + + dynamic get value; +} + +class FieldValue implements FieldValueInterface { + FieldValue._(this.type, this.value); + + @override + FieldValueInterface get instance => this; + + final FieldValueType type; + + final dynamic value; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart new file mode 100644 index 000000000000..a7ee11c62f9b --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -0,0 +1,49 @@ +part of cloud_firestore_platform_interface; + +enum FieldValueType { + arrayUnion, + arrayRemove, + delete, + serverTimestamp, + incrementDouble, + incrementInteger, +} + +abstract class FieldValueFactory { + + static FieldValueFactory get instance => _instance; + + static FieldValueFactory _instance = MethodChannelFieldValueFactory(); + + static set instance(FieldValueFactory instance) { + _instance = instance; + } + + /// Returns a special value that tells the server to union the given elements + /// with any array value that already exists on the server. + /// + /// Each specified element that doesn't already exist in the array will be + /// added to the end. If the field being modified is not already an array it + /// will be overwritten with an array containing exactly the specified + /// elements. + FieldValueInterface arrayUnion(List elements); + + /// Returns a special value that tells the server to remove the given + /// elements from any array value that already exists on the server. + /// + /// All instances of each element specified will be removed from the array. + /// If the field being modified is not already an array it will be overwritten + /// with an empty array. + FieldValueInterface arrayRemove(List elements); + + /// Returns a sentinel for use with update() to mark a field for deletion. + FieldValueInterface delete(); + + /// Returns a sentinel for use with set() or update() to include a + /// server-generated timestamp in the written data. + FieldValueInterface serverTimestamp(); + + /// Returns a special value for use with set() or update() that tells the + /// server to increment the field’s current value by the given value. + FieldValueInterface increment(num value); +} \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 687871414334..6d0049d8f49a 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -1149,12 +1149,12 @@ void main() { }); test('encode and decode FieldValue', () { - _checkEncodeDecode(codec, FieldValue.arrayUnion([123])); - _checkEncodeDecode(codec, FieldValue.arrayRemove([123])); - _checkEncodeDecode(codec, FieldValue.delete()); - _checkEncodeDecode(codec, FieldValue.serverTimestamp()); - _checkEncodeDecode(codec, FieldValue.increment(1.0)); - _checkEncodeDecode(codec, FieldValue.increment(1)); + _checkEncodeDecode(codec, FieldValueFactory.instance.arrayUnion([123])); + _checkEncodeDecode(codec, FieldValueFactory.instance.arrayRemove([123])); + _checkEncodeDecode(codec, FieldValueFactory.instance.delete()); + _checkEncodeDecode(codec, FieldValueFactory.instance.serverTimestamp()); + _checkEncodeDecode(codec, FieldValueFactory.instance.increment(1.0)); + _checkEncodeDecode(codec, FieldValueFactory.instance.increment(1)); }); test('encode and decode FieldPath', () { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 41cc1e8bb165..dd4db2fa7a1b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -42,7 +42,7 @@ class CollectionReferenceWeb implements CollectionReference { @override Future add(Map data) async { final DocumentReference newDocument = document(); - await newDocument.setData(data); + await newDocument.setData(FieldValueWeb._serverDelegates(data)); return newDocument; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 0eb8ff388776..2a95f4fce2e6 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -3,42 +3,40 @@ part of cloud_firestore_web; class DocumentReferenceWeb extends DocumentReference { final web.Firestore firestoreWeb; final web.DocumentReference delegate; - DocumentReferenceWeb(this.firestoreWeb,FirestorePlatform firestore, List pathComponents) - : delegate = firestoreWeb.doc(pathComponents.join("/")),super(firestore, pathComponents); + + DocumentReferenceWeb(this.firestoreWeb, FirestorePlatform firestore, + List pathComponents) + : delegate = firestoreWeb.doc(pathComponents.join("/")), + super(firestore, pathComponents); @override - Future setData(Map data, {bool merge = false}) { - return delegate.set(data, web.SetOptions(merge: merge)); - } + Future setData(Map data, {bool merge = false}) => + delegate.set(FieldValueWeb._serverDelegates(data), web.SetOptions(merge: merge)); @override - Future updateData(Map data) { - return delegate.update(data: data); - } + Future updateData(Map data) => + delegate.update(data: data); @override Future get({Source source = Source.serverAndCache}) async { + //TODO(amr): Honour source by passing it to the delegate return _fromWeb(await delegate.get()); } @override - Future delete() { - return delegate.delete(); - } + Future delete() => delegate.delete(); @override - Stream snapshots({bool includeMetadataChanges = false}) { - return delegate - .onSnapshot - .map((web.DocumentSnapshot webSnapshot) => _fromWeb(webSnapshot)); - } - - DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( - webSnapshot.ref.path, - webSnapshot.data(), - SnapshotMetadata( - webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache, - ), - this.firestore); + Stream snapshots({bool includeMetadataChanges = false}) => + delegate.onSnapshot.map(_fromWeb); + + DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => + DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + this.firestore); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart new file mode 100644 index 000000000000..562ceb2d3bf4 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -0,0 +1,35 @@ +part of cloud_firestore_web; + +class FieldValueFactoryWeb implements FieldValueFactory { + @override + FieldValueInterface arrayRemove(List elements) { + final delegate = web.FieldValue.arrayRemove(elements); + return FieldValueWeb._(delegate, FieldValueType.arrayRemove, elements); + } + + @override + FieldValueInterface arrayUnion(List elements) { + final delegate = web.FieldValue.arrayUnion(elements); + return FieldValueWeb._(delegate, FieldValueType.arrayUnion, elements); + } + + @override + FieldValueInterface delete() { + final delegate = web.FieldValue.delete(); + return FieldValueWeb._(delegate, FieldValueType.delete, null); + } + + @override + FieldValueInterface increment(num value) { + assert(num is double || num is int, "value can only be double or int"); + final delegate = web.FieldValue.increment(value); + return FieldValueWeb._(delegate, value is double ? FieldValueType.incrementDouble : FieldValueType.incrementDouble, value); + } + + @override + FieldValueInterface serverTimestamp() { + final delegate = web.FieldValue.serverTimestamp(); + return FieldValueWeb._(delegate, FieldValueType.serverTimestamp, null); + } + +} \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart new file mode 100644 index 000000000000..09ca10e57170 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -0,0 +1,28 @@ +part of cloud_firestore_web; + +class FieldValueWeb implements FieldValueInterface, web.FieldValue { + static Map _serverDelegates(Map data) { + Map output = Map.from(data); + output.updateAll((key, value) { + if(value is FieldValueInterface && value.instance is FieldValueWeb) { + return (value.instance as FieldValueWeb)._delegate; + } else{ + return value; + } + }); + return output; + } + + web.FieldValue _delegate; + + FieldValueWeb._(this._delegate, this.type, this.value); + + @override + final FieldValueType type; + + @override + final dynamic value; + + @override + FieldValueInterface get instance => this; +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index ad7317e23e31..57c75895969b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,32 +4,36 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; part 'collection_reference_web.dart'; +part 'field_value_factory_web.dart'; part 'document_reference_web.dart'; part 'query_web.dart'; part 'transaction_web.dart'; +part 'field_value_web.dart'; class FirestoreWeb extends FirestorePlatform { - final Firestore webFirestore; static void registerWith(Registrar registrar) { FirestorePlatform.instance = FirestoreWeb(); - + FieldValueFactory.instance = FieldValueFactoryWeb(); } - FirestoreWeb({FirebaseApp app}): webFirestore = firebase.firestore(firebase.app((app ?? FirebaseApp.instance).name)),super(app: app ?? FirebaseApp.instance); + FirestoreWeb({FirebaseApp app}) + : webFirestore = firebase + .firestore(firebase.app((app ?? FirebaseApp.instance).name)), + super(app: app ?? FirebaseApp.instance); @override FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); @override CollectionReference collection(String path) { - return CollectionReferenceWeb( - this, webFirestore, path.split('/')); + return CollectionReferenceWeb(this, webFirestore, path.split('/')); } @override @@ -65,7 +69,8 @@ class FirestoreWeb extends FirestorePlatform { } @override - Future> runTransaction(TransactionHandler transactionHandler, + Future> runTransaction( + TransactionHandler transactionHandler, {Duration timeout = const Duration(seconds: 5)}) { return webFirestore.runTransaction((transaction) { transactionHandler(TransactionWeb._(transaction, this)); @@ -74,5 +79,4 @@ class FirestoreWeb extends FirestorePlatform { @override String appName() => app.name; - } diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index 334f819c27df..7aa15838dc13 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -19,13 +19,13 @@ dependencies: http_parser: ^3.1.3 meta: ^1.1.7 firebase_core: ^0.4.3+1 - cloud_firestore_platform_interface: any + cloud_firestore_platform_interface: + path: ../cloud_firestore_platform_interface js: ^0.6.1 dev_dependencies: flutter_test: sdk: flutter - cloud_firestore: any firebase_core_platform_interface: ^1.0.0 environment: From ec595fe6ee47392f787147032ffcd4c850611c50 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 13:00:22 +0000 Subject: [PATCH 022/144] Build example for web and mobile Added NO-OP folders for android & ios in firestore web package --- .../example/ios/Flutter/Flutter.podspec | 18 ++++++++++ .../cloud_firestore/lib/cloud_firestore.dart | 2 +- .../cloud_firestore_web/android/.gitignore | 8 +++++ .../cloud_firestore_web/android/build.gradle | 33 +++++++++++++++++++ .../android/gradle.properties | 2 ++ .../gradle/wrapper/gradle-wrapper.properties | 5 +++ .../android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 3 ++ .../FirestoreWebPlugin.java | 15 +++++++++ .../ios/cloud_firestore_web.podspec | 21 ++++++++++++ 10 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 packages/cloud_firestore/cloud_firestore/example/ios/Flutter/Flutter.podspec create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/.gitignore create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/build.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/settings.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java create mode 100644 packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec diff --git a/packages/cloud_firestore/cloud_firestore/example/ios/Flutter/Flutter.podspec b/packages/cloud_firestore/cloud_firestore/example/ios/Flutter/Flutter.podspec new file mode 100644 index 000000000000..5ca30416bac0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/example/ios/Flutter/Flutter.podspec @@ -0,0 +1,18 @@ +# +# NOTE: This podspec is NOT to be published. It is only used as a local source! +# + +Pod::Spec.new do |s| + s.name = 'Flutter' + s.version = '1.0.0' + s.summary = 'High-performance, high-fidelity mobile apps.' + s.description = <<-DESC +Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. + DESC + s.homepage = 'https://flutter.io' + s.license = { :type => 'MIT' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } + s.ios.deployment_target = '8.0' + s.vendored_frameworks = 'Flutter.framework' +end diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 084a0f20339d..d8acbce0de65 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -16,7 +16,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; -export 'package:cloud_firestore_web/firestore_web.dart'; + part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore new file mode 100644 index 000000000000..c6cbe562a427 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle new file mode 100644 index 000000000000..e3db786e3805 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle @@ -0,0 +1,33 @@ +group 'io.flutter.plugins.cloud_firestore_web' +version '1.0' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties new file mode 100644 index 000000000000..3148384dab31 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..019065d1d650 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle new file mode 100644 index 000000000000..6bbf9cba49da --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'cloud_firestore_web' diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..ff4f493a984c --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java new file mode 100644 index 000000000000..af02befd488e --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java @@ -0,0 +1,15 @@ +package io.flutter.plugins.cloud_firestore_web; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +/** FirebaseAuthWebPlugin */ +public class FirestoreWebPlugin implements FlutterPlugin { + @Override + public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {} + + public static void registerWith(Registrar registrar) {} + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) {} +} diff --git a/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec b/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec new file mode 100644 index 000000000000..2e9b05c81076 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_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 = 'cloud_firestore_web' + s.version = '0.1.0' + s.summary = 'No-op implementation of cloud_firestore_web web plugin to avoid build issues on iOS' + s.description = <<-DESC + temp fake firebase_auth_web plugin + DESC + s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_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 + From aa7d42278edec78a996c4075cd5b58fe5cf2211d Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 13:13:10 +0000 Subject: [PATCH 023/144] Support new FieldValueInterface on mobile --- .../lib/src/method_channel_document_reference.dart | 4 ++-- .../lib/src/platform_interface/field_value.dart | 11 +++++++++++ .../lib/collection_reference_web.dart | 2 +- .../lib/document_reference_web.dart | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart index 4949191ba67b..ee0ee96fd58a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart @@ -15,7 +15,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': data, + 'data': FieldValue._serverDelegates(data), 'options': {'merge': merge}, }, ); @@ -28,7 +28,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': data, + 'data': FieldValue._serverDelegates(data), }, ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 4237f3ba6df9..c0942acf31e4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -17,6 +17,17 @@ abstract class FieldValueInterface { } class FieldValue implements FieldValueInterface { + static Map _serverDelegates(Map data) { + Map output = Map.from(data); + output.updateAll((key, value) { + if(value is FieldValueInterface && value.instance is FieldValue) { + return value.instance; + } else{ + return value; + } + }); + return output; + } FieldValue._(this.type, this.value); @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index dd4db2fa7a1b..41cc1e8bb165 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -42,7 +42,7 @@ class CollectionReferenceWeb implements CollectionReference { @override Future add(Map data) async { final DocumentReference newDocument = document(); - await newDocument.setData(FieldValueWeb._serverDelegates(data)); + await newDocument.setData(data); return newDocument; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 2a95f4fce2e6..fd5d489acf84 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -15,7 +15,7 @@ class DocumentReferenceWeb extends DocumentReference { @override Future updateData(Map data) => - delegate.update(data: data); + delegate.update(data: FieldValueWeb._serverDelegates(data)); @override Future get({Source source = Source.serverAndCache}) async { From 082baa3d4d6624315e53db2aa3eaf2b3bd39b7ce Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:38:30 +0000 Subject: [PATCH 024/144] Fix query delegation on web - Removed unnecessary tracking of collection reference delegate and used the more generic query type instead - fixed breakage --- .../lib/collection_reference_web.dart | 38 +++---- .../lib/firestore_web.dart | 4 +- .../cloud_firestore_web/lib/query_web.dart | 98 +++++++------------ 3 files changed, 55 insertions(+), 85 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 41cc1e8bb165..35a88c069caa 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -4,12 +4,12 @@ class CollectionReferenceWeb implements CollectionReference { final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; final List pathComponents; - final QueryWeb queryDelegate; + final QueryWeb _queryDelegate; CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) - : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), - webCollection: webFirestore.collection(pathComponents.join("/"))); + : _queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), + webFirestore.collection(pathComponents.join("/"))); @override DocumentReference parent() { @@ -47,28 +47,28 @@ class CollectionReferenceWeb implements CollectionReference { } @override - Map buildArguments() => queryDelegate.buildArguments(); + Map buildArguments() => _queryDelegate.buildArguments(); @override - Query endAt(List values) => queryDelegate.endAt(values); + Query endAt(List values) => _queryDelegate.endAt(values); @override Query endAtDocument(DocumentSnapshot documentSnapshot) => - queryDelegate.endAtDocument(documentSnapshot); + _queryDelegate.endAtDocument(documentSnapshot); @override - Query endBefore(List values) => queryDelegate.endBefore(values); + Query endBefore(List values) => _queryDelegate.endBefore(values); @override Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - queryDelegate.endBeforeDocument(documentSnapshot); + _queryDelegate.endBeforeDocument(documentSnapshot); @override FirestorePlatform get firestore => _firestorePlatform; @override Future getDocuments({Source source = Source.serverAndCache}) => - queryDelegate.getDocuments(source: source); + _queryDelegate.getDocuments(source: source); @override String get id => pathComponents.isEmpty ? null : pathComponents.last; @@ -77,38 +77,38 @@ class CollectionReferenceWeb implements CollectionReference { bool get isCollectionGroup => false; @override - Query limit(int length) => queryDelegate.limit(length); + Query limit(int length) => _queryDelegate.limit(length); @override Query orderBy(field, {bool descending = false}) => - queryDelegate.orderBy(field, descending: descending); + _queryDelegate.orderBy(field, descending: descending); @override - Map get parameters => queryDelegate.parameters; + Map get parameters => _queryDelegate.parameters; @override String get path => pathComponents.join("/"); @override - CollectionReference reference() => queryDelegate.reference(); + CollectionReference reference() => _queryDelegate.reference(); @override Stream snapshots({bool includeMetadataChanges = false}) => - queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); + _queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); @override - Query startAfter(List values) => queryDelegate.startAfter(values); + Query startAfter(List values) => _queryDelegate.startAfter(values); @override Query startAfterDocument(DocumentSnapshot documentSnapshot) => - queryDelegate.startAfterDocument(documentSnapshot); + _queryDelegate.startAfterDocument(documentSnapshot); @override - Query startAt(List values) => queryDelegate.startAt(values); + Query startAt(List values) => _queryDelegate.startAt(values); @override Query startAtDocument(DocumentSnapshot documentSnapshot) => - queryDelegate.startAtDocument(documentSnapshot); + _queryDelegate.startAtDocument(documentSnapshot); @override Query where(field, @@ -121,7 +121,7 @@ class CollectionReferenceWeb implements CollectionReference { List arrayContainsAny, List whereIn, bool isNull}) => - queryDelegate.where(field, + _queryDelegate.where(field, isEqualTo: isEqualTo, isLessThan: isLessThan, isLessThanOrEqualTo: isLessThanOrEqualTo, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 57c75895969b..0d2ee2cc921d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -38,8 +38,8 @@ class FirestoreWeb extends FirestorePlatform { @override Query collectionGroup(String path) { - return QueryWeb(this, path, - isCollectionGroup: true, webQuery: webFirestore.collectionGroup(path)); + return QueryWeb(this, path,webFirestore.collectionGroup(path), + isCollectionGroup: true); } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 601ec3f32976..82572366f58d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,39 +1,25 @@ part of cloud_firestore_web; class QueryWeb implements Query { - final web.CollectionReference webCollection; final web.Query webQuery; final FirestorePlatform _firestore; final bool _isCollectionGroup; final String _path; - QueryWeb(this._firestore, this._path, - {bool isCollectionGroup, this.webCollection, this.webQuery}) + QueryWeb(this._firestore, this._path, this.webQuery, {bool isCollectionGroup}) : this._isCollectionGroup = isCollectionGroup ?? false; @override Stream snapshots({bool includeMetadataChanges = false}) { - assert(webQuery != null || webCollection != null); - Stream webSnapshots; - if (webQuery != null) { - webSnapshots = webQuery.onSnapshot; - } else if (webCollection != null) { - webSnapshots = webCollection.onSnapshot; - } - return webSnapshots.map(_webQuerySnapshotToQuerySnapshot); + assert(webQuery != null); + return webQuery.onSnapshot.map(_webQuerySnapshotToQuerySnapshot); } @override Future getDocuments( {Source source = Source.serverAndCache}) async { - assert(webQuery != null || webCollection != null); - web.QuerySnapshot webDocuments; - if (webQuery != null) { - webDocuments = await webQuery.get(); - } else if (webCollection != null) { - webDocuments = await webCollection.get(); - } - return _webQuerySnapshotToQuerySnapshot(webDocuments); + assert(webQuery != null); + return _webQuerySnapshotToQuerySnapshot(await webQuery.get()); } @override @@ -43,26 +29,22 @@ class QueryWeb implements Query { @override Query endAt(List values) => QueryWeb(this._firestore, this._path, - webQuery: webQuery ?? webQuery.endAt(fieldValues: values), - webCollection: webCollection ?? webCollection.endAt(fieldValues: values)); + webQuery != null ? webQuery.endAt(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup); @override Query endAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb(this._firestore, this._path, - webQuery: _generateOrderByQuery(documentSnapshot) - .endAt(fieldValues: documentSnapshot.data.values)); + _generateOrderByQuery(documentSnapshot).endAt(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); @override Query endBefore(List values) => QueryWeb(this._firestore, this._path, - webQuery: webQuery ?? webQuery.endBefore(fieldValues: values), - webCollection: - webCollection ?? webCollection.endBefore(fieldValues: values)); + webQuery != null ? webQuery.endBefore(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); @override Query endBeforeDocument(DocumentSnapshot documentSnapshot) => QueryWeb(this._firestore, this._path, - webQuery: _generateOrderByQuery(documentSnapshot) - .endBefore(fieldValues: documentSnapshot.data.values)); + _generateOrderByQuery(documentSnapshot).endBefore(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); @override FirestorePlatform get firestore => _firestore; @@ -71,18 +53,14 @@ class QueryWeb implements Query { bool get isCollectionGroup => _isCollectionGroup; @override - Query limit(int length) => QueryWeb(this._firestore, this._path, - webQuery: webQuery ?? webQuery.limit(length), - webCollection: webCollection ?? webCollection.limit(length)); + Query limit(int length) => QueryWeb(this._firestore, this._path, webQuery != null ? webQuery.limit(length) : null,isCollectionGroup: _isCollectionGroup,); @override Query orderBy(field, {bool descending = false}) => QueryWeb( this._firestore, this._path, - webQuery: - webQuery ?? webQuery.orderBy(field, descending ? "desc" : "asc"), - webCollection: webCollection ?? - webCollection.orderBy(field, descending ? "desc" : "asc"), + webQuery.orderBy(field, descending ? "desc" : "asc"), + isCollectionGroup: _isCollectionGroup, ); @override @@ -101,31 +79,29 @@ class QueryWeb implements Query { Query startAfter(List values) => QueryWeb( this._firestore, this._path, - webQuery: webQuery ?? webQuery.startAfter(fieldValues: values), - webCollection: - webCollection ?? webCollection.startAfter(fieldValues: values), + webQuery.startAfter(fieldValues: values), + isCollectionGroup: _isCollectionGroup ); @override Query startAfterDocument(DocumentSnapshot documentSnapshot) => QueryWeb(this._firestore, this._path, - webQuery: _generateOrderByQuery(documentSnapshot) - .startAfter(fieldValues: documentSnapshot.data.values)); + _generateOrderByQuery(documentSnapshot) + .startAfter(fieldValues: documentSnapshot.data.values),isCollectionGroup: _isCollectionGroup); @override Query startAt(List values) => QueryWeb( this._firestore, this._path, - webQuery: webQuery ?? webQuery.startAt(fieldValues: values), - webCollection: - webCollection ?? webCollection.startAt(fieldValues: values), + webQuery.startAt(fieldValues: values) , + isCollectionGroup: _isCollectionGroup, ); @override Query startAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb(this._firestore, this._path, - webQuery: _generateOrderByQuery(documentSnapshot) - .startAt(fieldValues: documentSnapshot.data.values)); + _generateOrderByQuery(documentSnapshot) + .startAt(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); @override Query where(field, @@ -140,13 +116,10 @@ class QueryWeb implements Query { bool isNull}) { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); - assert(webQuery != null || webCollection != null); - web.Query query; - if (webQuery != null) { - query = webQuery; - } else if (webCollection != null) { - query = webCollection; - } + assert(webQuery != null); + + web.Query query = webQuery; + if (isEqualTo != null) { query = query.where(field, "==", isEqualTo); } @@ -182,11 +155,11 @@ class QueryWeb implements Query { 'Use isEqualTo to filter on non-null values.'); query = query.where(field, "==", null); } - return QueryWeb(this._firestore, this._path, webQuery: query); + return QueryWeb(this._firestore, this._path, query, isCollectionGroup: _isCollectionGroup); } QuerySnapshot _webQuerySnapshotToQuerySnapshot( - web.QuerySnapshot webSnapshot) { + web.QuerySnapshot webSnapshot) { return QuerySnapshot( webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot).toList(), webSnapshot.docChanges().map(_webChangeToChange).toList(), @@ -195,12 +168,14 @@ class QueryWeb implements Query { DocumentChange _webChangeToChange(web.DocumentChange webChange) { return DocumentChange( - _fromString(webChange.type), webChange.oldIndex, webChange.newIndex, + _fromString(webChange.type), + webChange.oldIndex, + webChange.newIndex, _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); } DocumentChangeType _fromString(String item) { - switch(item.toLowerCase()) { + switch (item.toLowerCase()) { case "added": return DocumentChangeType.added; case "modified": @@ -223,15 +198,10 @@ class QueryWeb implements Query { } web.Query _generateOrderByQuery(DocumentSnapshot webSnapshot) { - assert(webQuery != null || webCollection != null); - web.Query query; - if (webQuery != null) { - query = webQuery; - } else if (webCollection != null) { - query = webCollection; - } + assert(webQuery != null); + web.Query query = webQuery; webSnapshot.data.keys.forEach((key) => query = query.orderBy(key)); - return query.endAt(fieldValues: webSnapshot.data.values); + return query; } SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { From 61cc5b145f1a407c663f5cc283635b50eb4ef5bb Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:51:39 +0000 Subject: [PATCH 025/144] Use PlaformUtils for conversions in DocumentChange --- .../cloud_firestore/lib/cloud_firestore.dart | 2 +- .../lib/src/document_change.dart | 15 ++------------- .../lib/src/document_reference.dart | 2 +- .../cloud_firestore/lib/src/query.dart | 18 ++++++------------ ...PlatformUtils.dart => platform_utils.dart} | 19 ++++++++++++++++--- 5 files changed, 26 insertions(+), 30 deletions(-) rename packages/cloud_firestore/cloud_firestore/lib/src/utils/{PlatformUtils.dart => platform_utils.dart} (53%) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index d8acbce0de65..bbe06e0153f6 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -20,7 +20,7 @@ import 'package:meta/meta.dart'; part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; -part 'src/utils/PlatformUtils.dart'; +part 'src/utils/platform_utils.dart'; part 'src/document_reference.dart'; part 'src/document_snapshot.dart'; part 'src/field_path.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 2af4116a5115..056d0adeef11 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -28,7 +28,7 @@ class DocumentChange { DocumentChange._(this._delegate); /// The type of change that occurred (added, modified, or removed). - DocumentChangeType get type => _fromPlatform(_delegate.type); + DocumentChangeType get type => _PlatformUtils.fromPlatform(_delegate.type); /// The index of the changed document in the result set immediately prior to /// this [DocumentChange] (i.e. supposing that all prior DocumentChange objects @@ -48,16 +48,5 @@ class DocumentChange { DocumentSnapshot get document => DocumentSnapshot._(_delegate.document); - DocumentChangeType _fromPlatform(platform.DocumentChangeType platformChange) { - switch (platformChange) { - case platform.DocumentChangeType.added: - return DocumentChangeType.added; - case platform.DocumentChangeType.modified: - return DocumentChangeType.modified; - case platform.DocumentChangeType.removed: - return DocumentChangeType.removed; - default: - throw ArgumentError("Invalud change type"); - } - } + } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 5e977b4611b8..aca3db813fa3 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -62,7 +62,7 @@ class DocumentReference { /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { return DocumentSnapshot._( - await _delegate.get(source: PlatformUtils._toPlatformSource(source)) + await _delegate.get(source: _PlatformUtils.toPlatformSource(source)) ); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 0a67b699e5a6..c9c206352672 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -32,14 +32,8 @@ class Query { Future getDocuments( {Source source = Source.serverAndCache}) async { assert(source != null); - try{ - final docs = await _delegate.getDocuments(source: PlatformUtils._toPlatformSource(source)); - - return QuerySnapshot._(docs); - }catch(error) { - - throw error; - } + final docs = await _delegate.getDocuments(source: _PlatformUtils.toPlatformSource(source)); + return QuerySnapshot._(docs); } /// Obtains a CollectionReference corresponding to this query's location. @@ -108,7 +102,7 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query startAfterDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAfterDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.startAfterDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Creates and returns a new [Query] that starts at the provided document /// (inclusive). The starting position is relative to the order of the query. @@ -125,7 +119,7 @@ class Query { /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. Query startAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAtDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.startAtDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that starts @@ -165,7 +159,7 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. Query endAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endAtDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.endAtDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends at the /// provided fields relative to the order of the query. @@ -193,7 +187,7 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endBeforeDocument(PlatformUtils._toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.endBeforeDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends before /// the provided fields relative to the order of the query. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart similarity index 53% rename from packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart rename to packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart index 0293d31fa35e..d6610c1a0262 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/PlatformUtils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart @@ -1,7 +1,20 @@ part of cloud_firestore; -class PlatformUtils { - static platform.Source _toPlatformSource(Source platformSource) { +class _PlatformUtils { + static DocumentChangeType fromPlatform(platform.DocumentChangeType platformChange) { + switch (platformChange) { + case platform.DocumentChangeType.added: + return DocumentChangeType.added; + case platform.DocumentChangeType.modified: + return DocumentChangeType.modified; + case platform.DocumentChangeType.removed: + return DocumentChangeType.removed; + default: + throw ArgumentError("Invalud change type"); + } + } + + static platform.Source toPlatformSource(Source platformSource) { switch (platformSource) { case Source.cache: return platform.Source.cache; @@ -15,7 +28,7 @@ class PlatformUtils { } } - static platform.DocumentSnapshot _toPlatformDocumentSnapshot( + static platform.DocumentSnapshot toPlatformDocumentSnapshot( DocumentSnapshot documentSnapshot) => platform.DocumentSnapshot( documentSnapshot.reference.path, From aa3089ef549d77154ce8dffb0564850fb92fb5da Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:52:28 +0000 Subject: [PATCH 026/144] Fixed typo in variable name --- packages/cloud_firestore/cloud_firestore/.gitignore | 2 +- .../cloud_firestore/lib/src/document_snapshot.dart | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/.gitignore b/packages/cloud_firestore/cloud_firestore/.gitignore index 47b826216be0..e6c72fe41467 100644 --- a/packages/cloud_firestore/cloud_firestore/.gitignore +++ b/packages/cloud_firestore/cloud_firestore/.gitignore @@ -1,2 +1,2 @@ ios/Classes/UserAgent.h -/example/.flutter-plugins-dependencies +.flutter-plugins-dependencies diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 8d880e56a0ff..953903d84a28 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -10,26 +10,26 @@ part of cloud_firestore; /// The data can be extracted with the data property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { - platform.DocumentSnapshot _deletage; + platform.DocumentSnapshot _delegate; Firestore _firestore = Firestore.instance; - DocumentSnapshot._(this._deletage); + DocumentSnapshot._(this._delegate); /// The reference that produced this snapshot - DocumentReference get reference => _firestore.document(_deletage.reference.path); + DocumentReference get reference => _firestore.document(_delegate.reference.path); /// Contains all the data of this snapshot - Map get data => _deletage.data; + Map get data => _delegate.data; /// Metadata about this snapshot concerning its source and if it has local /// modifications. - SnapshotMetadata get metadata=> SnapshotMetadata._(_deletage.metadata); + SnapshotMetadata get metadata=> SnapshotMetadata._(_delegate.metadata); /// Reads individual values from the snapshot dynamic operator [](String key) => data[key]; /// Returns the ID of the snapshot's document - String get documentID => _deletage.documentID; + String get documentID => _delegate.documentID; /// Returns `true` if the document exists. bool get exists => data != null; From 2d3e7127e20c90ca62a4d5b589d2a554779b8f95 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:54:01 +0000 Subject: [PATCH 027/144] Pass timeout value for transaction --- .../cloud_firestore/cloud_firestore/lib/src/firestore.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 8fa7b332e2e1..9e63bc93fd6a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -39,8 +39,10 @@ class Firestore { Future> runTransaction( TransactionHandler transactionHandler, {Duration timeout = const Duration(seconds: 5)}) { - return _delegate.runTransaction((platformTransaction) => - transactionHandler(Transaction._(platformTransaction))); + return _delegate.runTransaction( + (platformTransaction) => + transactionHandler(Transaction._(platformTransaction)), + timeout: timeout); } Future settings( From abed99e5146486ca8f40d8b779ea114701bfef13 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:57:20 +0000 Subject: [PATCH 028/144] Delete unused cloud_firestore/firestore_message_codec --- .../cloud_firestore/lib/cloud_firestore.dart | 1 - .../lib/src/firestore_message_codec.dart | 123 ------------------ 2 files changed, 124 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index bbe06e0153f6..d300d012701a 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -26,7 +26,6 @@ part 'src/document_snapshot.dart'; part 'src/field_path.dart'; part 'src/field_value.dart'; part 'src/firestore.dart'; -part 'src/firestore_message_codec.dart'; part 'src/geo_point.dart'; part 'src/query.dart'; part 'src/query_snapshot.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart deleted file mode 100644 index ebcb923dc4e6..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore_message_codec.dart +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -@visibleForTesting -class FirestoreMessageCodec extends StandardMessageCodec { - const FirestoreMessageCodec(); - - static const int _kDateTime = 128; - static const int _kGeoPoint = 129; - static const int _kDocumentReference = 130; - static const int _kBlob = 131; - static const int _kArrayUnion = 132; - static const int _kArrayRemove = 133; - static const int _kDelete = 134; - static const int _kServerTimestamp = 135; - static const int _kTimestamp = 136; - static const int _kIncrementDouble = 137; - static const int _kIncrementInteger = 138; - static const int _kDocumentId = 139; - - static const Map _kFieldValueCodes = - { - platform.FieldValueType.arrayUnion: _kArrayUnion, - platform.FieldValueType.arrayRemove: _kArrayRemove, - platform.FieldValueType.delete: _kDelete, - platform.FieldValueType.serverTimestamp: _kServerTimestamp, - platform.FieldValueType.incrementDouble: _kIncrementDouble, - platform.FieldValueType.incrementInteger: _kIncrementInteger, - }; - - static const Map<_FieldPathType, int> _kFieldPathCodes = - <_FieldPathType, int>{ - _FieldPathType.documentId: _kDocumentId, - }; - - @override - void writeValue(WriteBuffer buffer, dynamic value) { - if (value is DateTime) { - buffer.putUint8(_kDateTime); - buffer.putInt64(value.millisecondsSinceEpoch); - } else if (value is Timestamp) { - buffer.putUint8(_kTimestamp); - buffer.putInt64(value.seconds); - buffer.putInt32(value.nanoseconds); - } else if (value is GeoPoint) { - buffer.putUint8(_kGeoPoint); - buffer.putFloat64(value.latitude); - buffer.putFloat64(value.longitude); - } else if (value is DocumentReference) { - buffer.putUint8(_kDocumentReference); - final List appName = utf8.encoder.convert(value.firestore.appName()); - writeSize(buffer, appName.length); - buffer.putUint8List(appName); - final List bytes = utf8.encoder.convert(value.path); - writeSize(buffer, bytes.length); - buffer.putUint8List(bytes); - } else if (value is Blob) { - buffer.putUint8(_kBlob); - writeSize(buffer, value.bytes.length); - buffer.putUint8List(value.bytes); - } else if (value is FieldValue) { - final int code = _kFieldValueCodes[value.type]; - assert(code != null); - buffer.putUint8(code); - if (value.value != null) writeValue(buffer, value.value); - } else if (value is FieldPath) { - final int code = _kFieldPathCodes[value.type]; - assert(code != null); - buffer.putUint8(code); - } else { - super.writeValue(buffer, value); - } - } - - @override - dynamic readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case _kDateTime: - return DateTime.fromMillisecondsSinceEpoch(buffer.getInt64()); - case _kTimestamp: - return Timestamp(buffer.getInt64(), buffer.getInt32()); - case _kGeoPoint: - return GeoPoint(buffer.getFloat64(), buffer.getFloat64()); - case _kDocumentReference: - final int appNameLength = readSize(buffer); - final String appName = - utf8.decoder.convert(buffer.getUint8List(appNameLength)); - final FirebaseApp app = FirebaseApp(name: appName); - final Firestore firestore = Firestore(app: app); - final int pathLength = readSize(buffer); - final String path = - utf8.decoder.convert(buffer.getUint8List(pathLength)); - return firestore.document(path); - case _kBlob: - final int length = readSize(buffer); - final List bytes = buffer.getUint8List(length); - return Blob(bytes); - case _kArrayUnion: - final List value = readValue(buffer); - return FieldValue.arrayUnion(value); - case _kArrayRemove: - final List value = readValue(buffer); - return FieldValue.arrayRemove(value); - case _kDelete: - return FieldValue.delete(); - case _kServerTimestamp: - return FieldValue.serverTimestamp(); - case _kIncrementDouble: - final double value = readValue(buffer); - return FieldValue.increment(value); - case _kIncrementInteger: - final int value = readValue(buffer); - return FieldValue.increment(value); - case _kDocumentId: - return FieldPath.documentId; - default: - return super.readValueOfType(type, buffer); - } - } -} From 269d71ef158c3902897d56a9dc9e5a32ee02e1c8 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 14:59:33 +0000 Subject: [PATCH 029/144] removed unused imports --- .../cloud_firestore/cloud_firestore/lib/cloud_firestore.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index d300d012701a..605d03dd3f68 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -5,7 +5,6 @@ library cloud_firestore; import 'dart:async'; -import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui' show hashValues, hashList; @@ -13,7 +12,6 @@ import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; From d820fbc49d40cd43ee27914fabdc106a72f251ad Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:00:16 +0000 Subject: [PATCH 030/144] removed empty constructor --- .../cloud_firestore/lib/src/query_snapshot.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 26b34397bab7..49081fee7d2d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -8,9 +8,7 @@ part of cloud_firestore; class QuerySnapshot { final platform.QuerySnapshot _delegate; - QuerySnapshot._(this._delegate) { - - } + QuerySnapshot._(this._delegate); /// Gets a list of all the documents included in this snapshot List get documents => From 685d16874f34aa6fb23853c7be92f788ff50751f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:01:34 +0000 Subject: [PATCH 031/144] Fixed argument name --- .../cloud_firestore/lib/src/utils/platform_utils.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart index d6610c1a0262..dc42ee25100a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart @@ -14,8 +14,8 @@ class _PlatformUtils { } } - static platform.Source toPlatformSource(Source platformSource) { - switch (platformSource) { + static platform.Source toPlatformSource(Source source) { + switch (source) { case Source.cache: return platform.Source.cache; case Source.server: From c6181310f595ec69612ee975c72ac7a532489571 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:08:41 +0000 Subject: [PATCH 032/144] Addressed comments for cloud_firestore_platform_interface setup --- .../cloud_firestore_platform_interface/.gitignore | 1 + .../cloud_firestore_platform_interface/.metadata | 10 ---------- .../cloud_firestore_platform_interface/CHANGELOG.md | 2 +- .../analysis_options.yaml | 5 ----- .../cloud_firestore_platform_interface/pubspec.yaml | 2 +- 5 files changed, 3 insertions(+), 17 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/.metadata diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore b/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore index bb431f0d5b47..2f9ef791f160 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/.gitignore @@ -14,6 +14,7 @@ *.ipr *.iws .idea/ +.metadata # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata b/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata deleted file mode 100644 index bae65c434b98..000000000000 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 18cd7a3601bcffb36fdf2f679f763b5e827c2e8e - channel: beta - -project_type: package diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md index b60fe9614434..0b8dff2e9d33 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/CHANGELOG.md @@ -1,3 +1,3 @@ -## [0.0.1] +## [1.0.0] * Created Platform Interface diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml index bbfa25e2146a..880f38c52a83 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml @@ -1,8 +1,3 @@ -# This is a temporary file to allow us to land a new set of linter rules in a -# series of manageable patches instead of one gigantic PR. It disables some of -# the new lints that are already failing on this plugin, for this plugin. It -# should be deleted and the failing lints addressed as soon as possible. - include: ../../../analysis_options.yaml analyzer: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml index 3357bbe781d8..0761e0d83c86 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml @@ -1,6 +1,6 @@ name: cloud_firestore_platform_interface description: A common platform interface for the cloud_firestore plugin. -version: 0.0.1 +version: 1.0.0 homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_platform_interface dependencies: From 874fdfb071df07f963e87265a0ded53e47d94edc Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:26:41 +0000 Subject: [PATCH 033/144] Use cast --- .../lib/src/document_snapshot.dart | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index 79d352f0a394..a3b1dc73514e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -35,11 +35,12 @@ class DocumentSnapshot { bool get exists => data != null; } -Map _asStringKeyedMap(Map map) { - if (map == null) return null; - if (map is Map) { - return map; - } else { - return Map.from(map); - } -} +Map _asStringKeyedMap(Map map) => + map?.cast(); +// if (map == null) return null; +// if (map is Map) { +// return map; +// } else { +// return Map.from(map); +// } +//} From 124501e91c060ac4dec7bb043db8fa982553e0b5 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:31:57 +0000 Subject: [PATCH 034/144] Add timeout to web transaction --- .../cloud_firestore/cloud_firestore_web/lib/firestore_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 0d2ee2cc921d..3f62ac4827fa 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -74,7 +74,7 @@ class FirestoreWeb extends FirestorePlatform { {Duration timeout = const Duration(seconds: 5)}) { return webFirestore.runTransaction((transaction) { transactionHandler(TransactionWeb._(transaction, this)); - }); + }).timeout(timeout); } @override From 3f182de04ee5ef04aa296f4b87490a758c590a50 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 15:34:05 +0000 Subject: [PATCH 035/144] Fixed cloud_firestore_web version --- packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md | 2 +- packages/cloud_firestore/cloud_firestore_web/README.md | 6 +++--- packages/cloud_firestore/cloud_firestore_web/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md index 8454a65ff176..e53776993662 100644 --- a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md @@ -1,3 +1,3 @@ -## 0.0.1 +## 0.1.0 - Initial release \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/README.md b/packages/cloud_firestore/cloud_firestore_web/README.md index 1788e7539e3c..b9d0e93f883d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/README.md +++ b/packages/cloud_firestore/cloud_firestore_web/README.md @@ -21,7 +21,7 @@ Add this to your `pubspec.yaml`: dependencies: ... cloud_firestore: ^0.13.1 - firebase_auth_web: ^0.0.1 + cloud_firestore_web: ^0.1.0 ... ``` @@ -45,8 +45,8 @@ In your app directory, edit `web/index.html` to add the line: ### Using the plugin -Once you have added the `firebase_auth_web` dependency to your pubspec, -you can use `package:firebase_auth` as normal. +Once you have added the `cloud_firebase_web` dependency to your pubspec, +you can use `package:cloud_firebase` as normal. [1]: ../cloud_firestore [2]: https://github.com/dart-lang/sdk/issues/33979 diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index 7aa15838dc13..f8415f84b312 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -1,7 +1,7 @@ name: cloud_firestore_web description: The web implementation of cloud_firestore homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_web -version: 0.0.1 +version: 0.1.0 flutter: plugin: From 8b93dfa30a6d04f2ce1aab04892d8c3652d10f54 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 17:30:04 +0000 Subject: [PATCH 036/144] Improved Query code and added documentation for main interface classes --- .../lib/src/method_channel_query.dart | 208 ++++++++++++++++++ .../src/platform_interface/field_value.dart | 15 +- .../field_value_factory.dart | 2 + .../lib/src/platform_interface/query.dart | 180 ++------------- .../platform_interface/query_snapshot.dart | 1 + .../cloud_firestore_web/lib/query_web.dart | 10 +- 6 files changed, 243 insertions(+), 173 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index e0df88dba327..188553dcc8bf 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. class MethodChannelQuery extends Query { + MethodChannelQuery( {@required FirestorePlatform firestore, @required List pathComponents, @@ -83,4 +84,211 @@ class MethodChannelQuery extends Query { ); return MethodChannelQuerySnapshot(data, firestore); } + + @override + Map buildArguments() => + Map.from(parameters) + ..addAll({ + 'path': path, + }); + + @override + Query where(field, {isEqualTo, isLessThan, isLessThanOrEqualTo, isGreaterThan, isGreaterThanOrEqualTo, arrayContains, List arrayContainsAny, List whereIn, bool isNull}) { + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + + final ListEquality equality = const ListEquality(); + final List> conditions = + List>.from(parameters['where']); + + void addCondition(dynamic field, String operator, dynamic value) { + final List condition = [field, operator, value]; + assert( + conditions + .where((List item) => equality.equals(condition, item)) + .isEmpty, + 'Condition $condition already exists in this query.'); + conditions.add(condition); + } + + if (isEqualTo != null) addCondition(field, '==', isEqualTo); + if (isLessThan != null) addCondition(field, '<', isLessThan); + if (isLessThanOrEqualTo != null) + addCondition(field, '<=', isLessThanOrEqualTo); + if (isGreaterThan != null) addCondition(field, '>', isGreaterThan); + if (isGreaterThanOrEqualTo != null) + addCondition(field, '>=', isGreaterThanOrEqualTo); + if (arrayContains != null) + addCondition(field, 'array-contains', arrayContains); + if (arrayContainsAny != null) + addCondition(field, 'array-contains-any', arrayContainsAny); + if (whereIn != null) addCondition(field, 'in', whereIn); + if (isNull != null) { + assert( + isNull, + 'isNull can only be set to true. ' + 'Use isEqualTo to filter on non-null values.'); + addCondition(field, '==', null); + } + + return _copyWithParameters({'where': conditions}); + } + + @override + Query orderBy(field, {bool descending = false}) { + assert(field != null && descending != null); + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + + final List> orders = + List>.from(parameters['orderBy']); + + final List order = [field, descending]; + assert(orders.where((List item) => field == item[0]).isEmpty, + 'OrderBy $field already exists in this query'); + + assert(() { + if (field == FieldPath.documentId) { + return !(parameters.containsKey('startAfterDocument') || + parameters.containsKey('startAtDocument') || + parameters.containsKey('endAfterDocument') || + parameters.containsKey('endAtDocument')); + } + return true; + }(), + '{start/end}{At/After/Before}Document order by document id themselves. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); + + orders.add(order); + return _copyWithParameters({'orderBy': orders}); + } + + @override + Query startAfterDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + assert( + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAfterDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); + return _copyWithParameters({ + 'startAfterDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + } + }); + } + + @override + Query startAtDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + assert( + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAtDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); + return _copyWithParameters({ + 'startAtDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + }, + }); + } + + @override + Query startAfter(List values) { + assert(values != null); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + return _copyWithParameters({'startAfter': values}); + } + + @override + Query startAt(List values) { + assert(values != null); + assert(!parameters.containsKey('startAfter')); + assert(!parameters.containsKey('startAt')); + assert(!parameters.containsKey('startAfterDocument')); + assert(!parameters.containsKey('startAtDocument')); + return _copyWithParameters({'startAt': values}); + } + + @override + Query endAtDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + assert( + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endAtDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); + + return _copyWithParameters({ + 'endAtDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data + }, + }); + } + + @override + Query endAt(List values) { + assert(values != null); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + return _copyWithParameters({'endAt': values}); + } + + @override + Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + assert(documentSnapshot != null); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + assert( + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endBeforeDocument] orders by document id itself. ' + 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); + return _copyWithParameters({ + 'endBeforeDocument': { + 'id': documentSnapshot.documentID, + 'path': documentSnapshot.reference.path, + 'data': documentSnapshot.data, + }, + }); + } + + @override + Query endBefore(List values) { + assert(values != null); + assert(!parameters.containsKey('endBefore')); + assert(!parameters.containsKey('endAt')); + assert(!parameters.containsKey('endBeforeDocument')); + assert(!parameters.containsKey('endAtDocument')); + return _copyWithParameters({'endBefore': values}); + } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index c0942acf31e4..976526d2a824 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -4,19 +4,25 @@ part of cloud_firestore_platform_interface; -/// Sentinel values that can be used when writing document fields with set() or -/// update(). - +/// A class to define an interface that's required +/// for building platform-specific implementation abstract class FieldValueInterface { + /// Implementation instance FieldValueInterface get instance; + /// type of the FieldValue FieldValueType get type; + /// value of the FieldValue dynamic get value; } +/// Mobile platform implementation for [FieldValueInterface] class FieldValue implements FieldValueInterface { + + /// Replaces items with type [FieldValueInterface] with implementation type + /// such as [FieldValue] static Map _serverDelegates(Map data) { Map output = Map.from(data); output.updateAll((key, value) { @@ -28,12 +34,15 @@ class FieldValue implements FieldValueInterface { }); return output; } + FieldValue._(this.type, this.value); @override FieldValueInterface get instance => this; + @override final FieldValueType type; + @override final dynamic value; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index a7ee11c62f9b..e63f168e480c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -1,5 +1,7 @@ part of cloud_firestore_platform_interface; +/// Sentinel values that can be used when writing document fields with set() or +/// update(). enum FieldValueType { arrayUnion, arrayRemove, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index e66b67c2a378..cc6a4dbccf53 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -24,21 +24,23 @@ abstract class Query { /// The Firestore instance associated with this query final FirestorePlatform firestore; + /// Represents the components of the path referenced by `this` [Query] final List pathComponents; + /// Map of the parameters used for filtering and sorting documents final Map parameters; + /// Indicates if `this` [Query] is for a collection group final bool isCollectionGroup; + /// Represents the path referenced by `this` [Query] String get path => pathComponents.join('/'); Query _copyWithParameters(Map parameters) { throw UnimplementedError("copyWithParameters() is not implemented"); } + /// Builds a map of all the parameters used and appends the [Query.path] Map buildArguments() { - return Map.from(parameters) - ..addAll({ - 'path': path, - }); + throw UnimplementedError("buildArguments() is not imlpmented"); } /// Notifies of query results at this location @@ -79,44 +81,7 @@ abstract class Query { List whereIn, bool isNull, }) { - assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); - - final ListEquality equality = const ListEquality(); - final List> conditions = - List>.from(parameters['where']); - - void addCondition(dynamic field, String operator, dynamic value) { - final List condition = [field, operator, value]; - assert( - conditions - .where((List item) => equality.equals(condition, item)) - .isEmpty, - 'Condition $condition already exists in this query.'); - conditions.add(condition); - } - - if (isEqualTo != null) addCondition(field, '==', isEqualTo); - if (isLessThan != null) addCondition(field, '<', isLessThan); - if (isLessThanOrEqualTo != null) - addCondition(field, '<=', isLessThanOrEqualTo); - if (isGreaterThan != null) addCondition(field, '>', isGreaterThan); - if (isGreaterThanOrEqualTo != null) - addCondition(field, '>=', isGreaterThanOrEqualTo); - if (arrayContains != null) - addCondition(field, 'array-contains', arrayContains); - if (arrayContainsAny != null) - addCondition(field, 'array-contains-any', arrayContainsAny); - if (whereIn != null) addCondition(field, 'in', whereIn); - if (isNull != null) { - assert( - isNull, - 'isNull can only be set to true. ' - 'Use isEqualTo to filter on non-null values.'); - addCondition(field, '==', null); - } - - return _copyWithParameters({'where': conditions}); + throw UnimplementedError("where() is not implemented"); } /// Creates and returns a new [Query] that's additionally sorted by the specified @@ -130,31 +95,7 @@ abstract class Query { /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. Query orderBy(dynamic field, {bool descending = false}) { - assert(field != null && descending != null); - assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); - - final List> orders = - List>.from(parameters['orderBy']); - - final List order = [field, descending]; - assert(orders.where((List item) => field == item[0]).isEmpty, - 'OrderBy $field already exists in this query'); - - assert(() { - if (field == FieldPath.documentId) { - return !(parameters.containsKey('startAfterDocument') || - parameters.containsKey('startAtDocument') || - parameters.containsKey('endAfterDocument') || - parameters.containsKey('endAtDocument')); - } - return true; - }(), - '{start/end}{At/After/Before}Document order by document id themselves. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); - - orders.add(order); - return _copyWithParameters({'orderBy': orders}); + throw UnimplementedError("orderBy() is not implemented"); } /// Creates and returns a new [Query] that starts after the provided document @@ -172,24 +113,7 @@ abstract class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query startAfterDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!parameters.containsKey('startAfter')); - assert(!parameters.containsKey('startAt')); - assert(!parameters.containsKey('startAfterDocument')); - assert(!parameters.containsKey('startAtDocument')); - assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAfterDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); - return _copyWithParameters({ - 'startAfterDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - } - }); + throw UnimplementedError("startAfterDocument() is not implemented"); } /// Creates and returns a new [Query] that starts at the provided document @@ -207,24 +131,7 @@ abstract class Query { /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. Query startAtDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!parameters.containsKey('startAfter')); - assert(!parameters.containsKey('startAt')); - assert(!parameters.containsKey('startAfterDocument')); - assert(!parameters.containsKey('startAtDocument')); - assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAtDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); - return _copyWithParameters({ - 'startAtDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - }, - }); + throw UnimplementedError("startAtDocument() is not implemented"); } /// Takes a list of [values], creates and returns a new [Query] that starts @@ -236,12 +143,7 @@ abstract class Query { /// [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. Query startAfter(List values) { - assert(values != null); - assert(!parameters.containsKey('startAfter')); - assert(!parameters.containsKey('startAt')); - assert(!parameters.containsKey('startAfterDocument')); - assert(!parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAfter': values}); + throw UnimplementedError("startAfter() is not implemented"); } /// Takes a list of [values], creates and returns a new [Query] that starts at @@ -253,12 +155,7 @@ abstract class Query { /// or [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. Query startAt(List values) { - assert(values != null); - assert(!parameters.containsKey('startAfter')); - assert(!parameters.containsKey('startAt')); - assert(!parameters.containsKey('startAfterDocument')); - assert(!parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAt': values}); + throw UnimplementedError("startAt() is not implemented"); } /// Creates and returns a new [Query] that ends at the provided document @@ -276,25 +173,7 @@ abstract class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. Query endAtDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!parameters.containsKey('endBefore')); - assert(!parameters.containsKey('endAt')); - assert(!parameters.containsKey('endBeforeDocument')); - assert(!parameters.containsKey('endAtDocument')); - assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endAtDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); - - return _copyWithParameters({ - 'endAtDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data - }, - }); + throw UnimplementedError("endAtDocument() is not implemented"); } /// Takes a list of [values], creates and returns a new [Query] that ends at the @@ -306,12 +185,7 @@ abstract class Query { /// [endAtDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. Query endAt(List values) { - assert(values != null); - assert(!parameters.containsKey('endBefore')); - assert(!parameters.containsKey('endAt')); - assert(!parameters.containsKey('endBeforeDocument')); - assert(!parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endAt': values}); + throw UnimplementedError("endAt() is not implemented"); } /// Creates and returns a new [Query] that ends before the provided document @@ -329,24 +203,7 @@ abstract class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query endBeforeDocument(DocumentSnapshot documentSnapshot) { - assert(documentSnapshot != null); - assert(!parameters.containsKey('endBefore')); - assert(!parameters.containsKey('endAt')); - assert(!parameters.containsKey('endBeforeDocument')); - assert(!parameters.containsKey('endAtDocument')); - assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endBeforeDocument] orders by document id itself. ' - 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); - return _copyWithParameters({ - 'endBeforeDocument': { - 'id': documentSnapshot.documentID, - 'path': documentSnapshot.reference.path, - 'data': documentSnapshot.data, - }, - }); + throw UnimplementedError("endBeforeDocument() is not implemented"); } /// Takes a list of [values], creates and returns a new [Query] that ends before @@ -358,12 +215,7 @@ abstract class Query { /// [endBeforeDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. Query endBefore(List values) { - assert(values != null); - assert(!parameters.containsKey('endBefore')); - assert(!parameters.containsKey('endAt')); - assert(!parameters.containsKey('endBeforeDocument')); - assert(!parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endBefore': values}); + throw UnimplementedError("endBefore() is not implemented"); } /// Creates and returns a new Query that's additionally limited to only return up diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 9b315e8f8d3a..67de0fca6842 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -16,5 +16,6 @@ class QuerySnapshot { /// is the first snapshot, all documents will be in the list as Added changes. final List documentChanges; + /// Metadata for the document final SnapshotMetadata metadata; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 82572366f58d..1cae21ce348a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -23,9 +23,7 @@ class QueryWeb implements Query { } @override - Map buildArguments() { - return null; - } + Map buildArguments() => Map(); @override Query endAt(List values) => QueryWeb(this._firestore, this._path, @@ -63,9 +61,6 @@ class QueryWeb implements Query { isCollectionGroup: _isCollectionGroup, ); - @override - Map get parameters => null; - @override String get path => this._path; @@ -208,4 +203,7 @@ class QueryWeb implements Query { return SnapshotMetadata( webMetadata.hasPendingWrites, webMetadata.fromCache); } + + @override + Map get parameters => Map(); } From b2e46f176cbde383ee200f6cff63fe7d0e5d054e Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 21:09:23 +0000 Subject: [PATCH 037/144] Minor PR fixes - Removed cupertino import - Removed wrong firebase config parameter - ignored auto-generated file --- .../cloud_firestore/cloud_firestore/.gitignore | 1 + .../cloud_firestore/analysis_options.yaml | 5 ----- .../example/lib/generated_plugin_registrant.dart | 15 --------------- .../cloud_firestore/example/web/index.html | 13 +++++-------- .../lib/src/document_snapshot.dart | 7 ------- .../cloud_firestore_web/lib/firestore_web.dart | 1 - 6 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart diff --git a/packages/cloud_firestore/cloud_firestore/.gitignore b/packages/cloud_firestore/cloud_firestore/.gitignore index e6c72fe41467..dd1148532910 100644 --- a/packages/cloud_firestore/cloud_firestore/.gitignore +++ b/packages/cloud_firestore/cloud_firestore/.gitignore @@ -1,2 +1,3 @@ ios/Classes/UserAgent.h .flutter-plugins-dependencies +generated_plugin_registrant.dart diff --git a/packages/cloud_firestore/cloud_firestore/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore/analysis_options.yaml index bbfa25e2146a..880f38c52a83 100644 --- a/packages/cloud_firestore/cloud_firestore/analysis_options.yaml +++ b/packages/cloud_firestore/cloud_firestore/analysis_options.yaml @@ -1,8 +1,3 @@ -# This is a temporary file to allow us to land a new set of linter rules in a -# series of manageable patches instead of one gigantic PR. It disables some of -# the new lints that are already failing on this plugin, for this plugin. It -# should be deleted and the failing lints addressed as soon as possible. - include: ../../../analysis_options.yaml analyzer: diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart b/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart deleted file mode 100644 index dc9465bdf947..000000000000 --- a/packages/cloud_firestore/cloud_firestore/example/lib/generated_plugin_registrant.dart +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// -import 'dart:ui'; - -import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:firebase_core_web/firebase_core_web.dart'; - -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -void registerPlugins(PluginRegistry registry) { - FirestoreWeb.registerWith(registry.registrarFor(FirestoreWeb)); - FirebaseCoreWeb.registerWith(registry.registrarFor(FirebaseCoreWeb)); - registry.registerMessageHandler(); -} diff --git a/packages/cloud_firestore/cloud_firestore/example/web/index.html b/packages/cloud_firestore/cloud_firestore/example/web/index.html index 07f2b9039607..d31bf55b8935 100644 --- a/packages/cloud_firestore/cloud_firestore/example/web/index.html +++ b/packages/cloud_firestore/cloud_firestore/example/web/index.html @@ -10,14 +10,11 @@ diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index a3b1dc73514e..ffdcca53185c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -37,10 +37,3 @@ class DocumentSnapshot { Map _asStringKeyedMap(Map map) => map?.cast(); -// if (map == null) return null; -// if (map is Map) { -// return map; -// } else { -// return Map.from(map); -// } -//} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 3f62ac4827fa..9446dcd87c08 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,7 +4,6 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; From 98bfeb29ecb9dac292c8a73910e571a4c23420f9 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 18 Dec 2019 21:57:40 +0000 Subject: [PATCH 038/144] Fixed current analyze and fmt issues --- .../cloud_firestore/lib/cloud_firestore.dart | 3 +- .../lib/src/collection_reference.dart | 8 +- .../lib/src/document_change.dart | 5 +- .../lib/src/document_reference.dart | 14 ++-- .../lib/src/document_snapshot.dart | 6 +- .../cloud_firestore/lib/src/field_value.dart | 2 +- .../cloud_firestore/lib/src/firestore.dart | 1 + .../cloud_firestore/lib/src/query.dart | 29 ++++--- .../lib/src/query_snapshot.dart | 4 +- .../cloud_firestore/lib/src/source.dart | 12 --- .../cloud_firestore/lib/src/transaction.dart | 3 +- .../lib/src/utils/platform_utils.dart | 4 +- .../cloud_firestore/lib/src/write_batch.dart | 13 ++-- .../cloud_firestore_platform_interface.dart | 13 ++-- .../lib/src/blob.dart | 2 +- .../method_channel_collection_reference.dart | 9 ++- .../method_channel_document_reference.dart | 10 ++- .../method_channel_field_value_factory.dart | 4 +- .../lib/src/method_channel_firestore.dart | 7 +- .../lib/src/method_channel_query.dart | 77 ++++++++++--------- .../collection_reference.dart | 2 +- .../document_reference_interface.dart | 9 ++- .../src/platform_interface/field_value.dart | 6 +- .../field_value_factory.dart | 3 +- .../lib/src/platform_interface/query.dart | 2 + .../platform_interface/query_snapshot.dart | 1 - .../lib/src/transaction.dart | 9 ++- .../lib/src/write_batch.dart | 3 +- .../src/write_batch_platform_interface.dart | 2 - .../method_channel_cloud_firestore_test.dart | 23 +++--- .../lib/document_reference_web.dart | 3 +- .../lib/field_value_factory_web.dart | 10 ++- .../lib/field_value_web.dart | 4 +- .../lib/firestore_web.dart | 2 +- .../cloud_firestore_web/lib/query_web.dart | 60 +++++++++------ .../lib/transaction_web.dart | 39 ++++++---- 36 files changed, 213 insertions(+), 191 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 605d03dd3f68..95342d193382 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -9,7 +9,8 @@ import 'dart:typed_data'; import 'dart:ui' show hashValues, hashList; import 'package:flutter/foundation.dart'; -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' + as platform; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/services.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index d8b1da33e733..0060deaaae65 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -10,7 +10,7 @@ part of cloud_firestore; class CollectionReference extends Query { final platform.CollectionReference _delegate; - CollectionReference._(this._delegate): super._(_delegate); + CollectionReference._(this._delegate) : super._(_delegate); /// ID of the referenced collection. String get id => _pathComponents.isEmpty ? null : _pathComponents.last; @@ -22,9 +22,7 @@ class CollectionReference extends Query { if (_pathComponents.length < 2) { return null; } - return DocumentReference._( - _delegate.parent() - ); + return DocumentReference._(_delegate.parent()); } /// A string containing the slash-separated path to this CollectionReference @@ -38,7 +36,7 @@ class CollectionReference extends Query { /// The unique key generated is prefixed with a client-generated timestamp /// so that the resulting list will be chronologically-sorted. DocumentReference document([String path]) => - DocumentReference._(_delegate.document(path)); + DocumentReference._(_delegate.document(path)); /// Returns a `DocumentReference` with an auto-generated ID, after /// populating it with provided [data]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 056d0adeef11..20ecb01fe4d3 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -45,8 +45,5 @@ class DocumentChange { int get newIndex => _delegate.newIndex; /// The document affected by this change. - DocumentSnapshot get document => - DocumentSnapshot._(_delegate.document); - - + DocumentSnapshot get document => DocumentSnapshot._(_delegate.document); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index aca3db813fa3..4d7417aa6bf8 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -26,9 +26,7 @@ class DocumentReference { /// Parent returns the containing [CollectionReference]. CollectionReference parent() { - return CollectionReference._( - _delegate.parent() - ); + return CollectionReference._(_delegate.parent()); } /// Slash-delimited path representing the database location of this query. @@ -44,7 +42,7 @@ class DocumentReference { /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. Future setData(Map data, {bool merge = false}) { - return _delegate.setData(data,merge: merge); + return _delegate.setData(data, merge: merge); } /// Updates fields in the document referred to by this [DocumentReference]. @@ -62,8 +60,7 @@ class DocumentReference { /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { return DocumentSnapshot._( - await _delegate.get(source: _PlatformUtils.toPlatformSource(source)) - ); + await _delegate.get(source: _PlatformUtils.toPlatformSource(source))); } /// Deletes the document referred to by this [DocumentReference]. @@ -79,6 +76,7 @@ class DocumentReference { /// Notifies of documents at this location Stream snapshots({bool includeMetadataChanges = false}) => - _delegate.snapshots(includeMetadataChanges: includeMetadataChanges) - .map((snapshot) => DocumentSnapshot._(snapshot)); + _delegate + .snapshots(includeMetadataChanges: includeMetadataChanges) + .map((snapshot) => DocumentSnapshot._(snapshot)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 953903d84a28..38bd582a666a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -14,16 +14,16 @@ class DocumentSnapshot { Firestore _firestore = Firestore.instance; DocumentSnapshot._(this._delegate); - /// The reference that produced this snapshot - DocumentReference get reference => _firestore.document(_delegate.reference.path); + DocumentReference get reference => + _firestore.document(_delegate.reference.path); /// Contains all the data of this snapshot Map get data => _delegate.data; /// Metadata about this snapshot concerning its source and if it has local /// modifications. - SnapshotMetadata get metadata=> SnapshotMetadata._(_delegate.metadata); + SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata); /// Reads individual values from the snapshot dynamic operator [](String key) => data[key]; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index f7ba79de1bfb..8b35597e7bf5 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -6,7 +6,7 @@ part of cloud_firestore; /// Sentinel values that can be used when writing document fields with set() or /// update(). -class FieldValue implements platform.FieldValueInterface{ +class FieldValue implements platform.FieldValueInterface { platform.FieldValueInterface _delegate; FieldValue._(this._delegate); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 9e63bc93fd6a..0b1cc9e7854c 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -33,6 +33,7 @@ class Firestore { DocumentReference document(String path) => DocumentReference._(_delegate.document(path)); + @deprecated Future enablePersistence(bool enable) => _delegate.enablePersistence(enable); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index c9c206352672..7502c284870e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -15,7 +15,6 @@ class Query { List get _pathComponents => _delegate.pathComponents; - String get _path => _pathComponents.join('/'); Map buildArguments() { @@ -32,7 +31,8 @@ class Query { Future getDocuments( {Source source = Source.serverAndCache}) async { assert(source != null); - final docs = await _delegate.getDocuments(source: _PlatformUtils.toPlatformSource(source)); + final docs = await _delegate.getDocuments( + source: _PlatformUtils.toPlatformSource(source)); return QuerySnapshot._(docs); } @@ -102,7 +102,8 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query startAfterDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAfterDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.startAfterDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Creates and returns a new [Query] that starts at the provided document /// (inclusive). The starting position is relative to the order of the query. @@ -119,8 +120,8 @@ class Query { /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. Query startAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAtDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); - + Query._(_delegate.startAtDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that starts /// after the provided fields relative to the order of the query. @@ -141,8 +142,7 @@ class Query { /// Cannot be used in combination with [startAfter], [startAfterDocument], /// or [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAt(List values) => - Query._(_delegate.startAt(values)); + Query startAt(List values) => Query._(_delegate.startAt(values)); /// Creates and returns a new [Query] that ends at the provided document /// (inclusive). The end position is relative to the order of the query. @@ -159,7 +159,8 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. Query endAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endAtDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.endAtDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends at the /// provided fields relative to the order of the query. @@ -169,8 +170,7 @@ class Query { /// Cannot be used in combination with [endBefore], [endBeforeDocument], or /// [endAtDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endAt(List values) => - Query._(_delegate.endAt(values)); + Query endAt(List values) => Query._(_delegate.endAt(values)); /// Creates and returns a new [Query] that ends before the provided document /// (exclusive). The end position is relative to the order of the query. @@ -187,7 +187,8 @@ class Query { /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endBeforeDocument(_PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query._(_delegate.endBeforeDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); /// Takes a list of [values], creates and returns a new [Query] that ends before /// the provided fields relative to the order of the query. @@ -197,11 +198,9 @@ class Query { /// Cannot be used in combination with [endAt], [endBeforeDocument], or /// [endBeforeDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endBefore(List values) => - Query._(_delegate.endBefore(values)); + Query endBefore(List values) => Query._(_delegate.endBefore(values)); /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. - Query limit(int length) => - Query._(_delegate.limit(length)); + Query limit(int length) => Query._(_delegate.limit(length)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 49081fee7d2d..89e43bf224c0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -16,8 +16,8 @@ class QuerySnapshot { /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. - List get documentChanges => _delegate.documentChanges - .map((item) => DocumentChange._(item)).toList(); + List get documentChanges => + _delegate.documentChanges.map((item) => DocumentChange._(item)).toList(); SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore/lib/src/source.dart index 0a0a43eef8f3..012762b6a84b 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/source.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/source.dart @@ -23,15 +23,3 @@ enum Source { /// [QuerySnapshot] with no documents. cache, } - -/// Converts [Source] to [String] -String _getSourceString(Source source) { - assert(source != null); - if (source == Source.server) { - return 'server'; - } - if (source == Source.cache) { - return 'cache'; - } - return 'default'; -} diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index f7cbe1634824..8e1158ebf1ba 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -7,12 +7,11 @@ part of cloud_firestore; typedef Future TransactionHandler(Transaction transaction); class Transaction { - Transaction._(this._delegate); platform.Transaction _delegate; - + // ignore: unused_element Future _finish() => _delegate.finish(); /// Reads the document referenced by the provided DocumentReference. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart index dc42ee25100a..ee8637c071a0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart @@ -1,7 +1,8 @@ part of cloud_firestore; class _PlatformUtils { - static DocumentChangeType fromPlatform(platform.DocumentChangeType platformChange) { + static DocumentChangeType fromPlatform( + platform.DocumentChangeType platformChange) { switch (platformChange) { case platform.DocumentChangeType.added: return DocumentChangeType.added; @@ -23,7 +24,6 @@ class _PlatformUtils { case Source.serverAndCache: return platform.Source.serverAndCache; default: - throw ArgumentError("Invalid source value"); } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 92ce33d2daca..849e7eb417b5 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -12,20 +12,23 @@ part of cloud_firestore; /// nor can it be committed again. class WriteBatch implements platform.WriteBatchPlatform { platform.WriteBatch _delegate; - WriteBatch._(): _delegate = platform.WriteBatch(platform.FirestorePlatform.instance); + WriteBatch._() + : _delegate = platform.WriteBatch(platform.FirestorePlatform.instance); @override Future commit() => _delegate.commit(); @override - void delete(platform.DocumentReference document) => _delegate.delete(document); + void delete(platform.DocumentReference document) => + _delegate.delete(document); @override - void setData(platform.DocumentReference document, Map data, {bool merge = false}) => + void setData(platform.DocumentReference document, Map data, + {bool merge = false}) => _delegate.setData(document, data, merge: merge); @override - void updateData(platform.DocumentReference document, Map data) => + void updateData( + platform.DocumentReference document, Map data) => _delegate.updateData(document, data); - } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 26ff14254559..0e5b9a81cbba 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -41,15 +41,15 @@ part 'src/write_batch.dart'; part 'src/write_batch_platform_interface.dart'; abstract class FirestorePlatform { - final FirebaseApp app; - FirestorePlatform({FirebaseApp app}): app = app ?? FirebaseApp.instance; + FirestorePlatform({FirebaseApp app}) : app = app ?? FirebaseApp.instance; factory FirestorePlatform.withApp({FirebaseApp app}) { FirestorePlatform.instance = FirestorePlatform.instance.withApp(app); return FirestorePlatform.instance; } + /// Only mock implementations should set this to `true`. /// /// Mockito mocks implement this class with `implements` which is forbidden @@ -147,10 +147,11 @@ abstract class FirestorePlatform { throw UnimplementedError('enablePersistence() is not implemented'); } - Future settings({bool persistenceEnabled, - String host, - bool sslEnabled, - int cacheSizeBytes}) async { + Future settings( + {bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) async { throw UnimplementedError('settings() is not implemented'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index 2e52eca55611..1f9e2efe8014 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -8,7 +8,7 @@ class Blob { @override bool operator ==(dynamic other) => other is Blob && - const DeepCollectionEquality().equals(other.bytes, bytes); + const DeepCollectionEquality().equals(other.bytes, bytes); @override int get hashCode => hashList(bytes); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart index a04d30be9d48..ed43a00cda09 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart @@ -7,9 +7,11 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [Query]). -class MethodChannelCollectionReference extends MethodChannelQuery implements CollectionReference { - MethodChannelCollectionReference(FirestorePlatform firestore, List pathComponents) - : super(firestore: firestore,pathComponents: pathComponents); +class MethodChannelCollectionReference extends MethodChannelQuery + implements CollectionReference { + MethodChannelCollectionReference( + FirestorePlatform firestore, List pathComponents) + : super(firestore: firestore, pathComponents: pathComponents); /// ID of the referenced collection. String get id => pathComponents.isEmpty ? null : pathComponents.last; @@ -43,5 +45,4 @@ class MethodChannelCollectionReference extends MethodChannelQuery implements Co await newDocument.setData(data); return newDocument; } - } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart index ee0ee96fd58a..1fe28155b242 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart @@ -5,9 +5,11 @@ part of cloud_firestore_platform_interface; class MethodChannelDocumentReference extends DocumentReference { - MethodChannelDocumentReference(FirestorePlatform firestore, List pathComponents) - :assert(firestore != null), super(firestore, pathComponents); - + MethodChannelDocumentReference( + FirestorePlatform firestore, List pathComponents) + : assert(firestore != null), + super(firestore, pathComponents); + @override Future setData(Map data, {bool merge = false}) { return MethodChannelFirestore.channel.invokeMethod( @@ -60,7 +62,7 @@ class MethodChannelDocumentReference extends DocumentReference { {'app': firestore.appName(), 'path': path}, ); } - + // TODO(jackson): Reduce code duplication with [Query] @override Stream snapshots({bool includeMetadataChanges = false}) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart index 376af0270fa0..f6a9461b00b7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart @@ -12,7 +12,6 @@ class MethodChannelFieldValueFactory implements FieldValueFactory { @override FieldValue delete() => FieldValue._(FieldValueType.delete, null); - @override FieldValue increment(num value) { // It is a compile-time error for any type other than int or double to @@ -29,5 +28,4 @@ class MethodChannelFieldValueFactory implements FieldValueFactory { @override FieldValue serverTimestamp() => FieldValue._(FieldValueType.serverTimestamp, null); - -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index bb9c4ec361cb..c7783fe75d3e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -8,13 +8,13 @@ part of cloud_firestore_platform_interface; /// /// You can get an instance by calling [Firestore.instance]. class MethodChannelFirestore extends FirestorePlatform { - MethodChannelFirestore({FirebaseApp app}) : super(app: app ?? FirebaseApp.instance) { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { - final QuerySnapshot snapshot = MethodChannelQuerySnapshot(call.arguments, this); + final QuerySnapshot snapshot = + MethodChannelQuerySnapshot(call.arguments, this); _queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { final DocumentSnapshot snapshot = DocumentSnapshot( @@ -58,7 +58,6 @@ class MethodChannelFirestore extends FirestorePlatform { {}; static int _transactionHandlerId = 0; - @override FirestorePlatform withApp(FirebaseApp app) => MethodChannelFirestore(app: app); @@ -131,7 +130,7 @@ class MethodChannelFirestore extends FirestorePlatform { 'cacheSizeBytes': cacheSizeBytes, }); } - + @override String appName() => app.name; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index 188553dcc8bf..727ac3c1a350 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -6,7 +6,6 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. class MethodChannelQuery extends Query { - MethodChannelQuery( {@required FirestorePlatform firestore, @required List pathComponents, @@ -86,28 +85,36 @@ class MethodChannelQuery extends Query { } @override - Map buildArguments() => - Map.from(parameters) - ..addAll({ - 'path': path, - }); + Map buildArguments() => Map.from(parameters) + ..addAll({ + 'path': path, + }); @override - Query where(field, {isEqualTo, isLessThan, isLessThanOrEqualTo, isGreaterThan, isGreaterThanOrEqualTo, arrayContains, List arrayContainsAny, List whereIn, bool isNull}) { + Query where(field, + {isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull}) { assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); + 'Supported [field] types are [String] and [FieldPath].'); final ListEquality equality = const ListEquality(); final List> conditions = - List>.from(parameters['where']); + List>.from(parameters['where']); void addCondition(dynamic field, String operator, dynamic value) { final List condition = [field, operator, value]; assert( - conditions - .where((List item) => equality.equals(condition, item)) - .isEmpty, - 'Condition $condition already exists in this query.'); + conditions + .where((List item) => equality.equals(condition, item)) + .isEmpty, + 'Condition $condition already exists in this query.'); conditions.add(condition); } @@ -125,8 +132,8 @@ class MethodChannelQuery extends Query { if (whereIn != null) addCondition(field, 'in', whereIn); if (isNull != null) { assert( - isNull, - 'isNull can only be set to true. ' + isNull, + 'isNull can only be set to true. ' 'Use isEqualTo to filter on non-null values.'); addCondition(field, '==', null); } @@ -138,14 +145,14 @@ class MethodChannelQuery extends Query { Query orderBy(field, {bool descending = false}) { assert(field != null && descending != null); assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); + 'Supported [field] types are [String] and [FieldPath].'); final List> orders = - List>.from(parameters['orderBy']); + List>.from(parameters['orderBy']); final List order = [field, descending]; assert(orders.where((List item) => field == item[0]).isEmpty, - 'OrderBy $field already exists in this query'); + 'OrderBy $field already exists in this query'); assert(() { if (field == FieldPath.documentId) { @@ -156,7 +163,7 @@ class MethodChannelQuery extends Query { } return true; }(), - '{start/end}{At/After/Before}Document order by document id themselves. ' + '{start/end}{At/After/Before}Document order by document id themselves. ' 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); orders.add(order); @@ -171,10 +178,10 @@ class MethodChannelQuery extends Query { assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAfterDocument] orders by document id itself. ' + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAfterDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); return _copyWithParameters({ 'startAfterDocument': { @@ -193,10 +200,10 @@ class MethodChannelQuery extends Query { assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[startAtDocument] orders by document id itself. ' + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[startAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); return _copyWithParameters({ 'startAtDocument': { @@ -235,10 +242,10 @@ class MethodChannelQuery extends Query { assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endAtDocument] orders by document id itself. ' + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); return _copyWithParameters({ @@ -268,10 +275,10 @@ class MethodChannelQuery extends Query { assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); assert( - List>.from(parameters['orderBy']) - .where((List item) => item[0] == FieldPath.documentId) - .isEmpty, - '[endBeforeDocument] orders by document id itself. ' + List>.from(parameters['orderBy']) + .where((List item) => item[0] == FieldPath.documentId) + .isEmpty, + '[endBeforeDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); return _copyWithParameters({ 'endBeforeDocument': { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index 012cf8a16433..05ae612cdba7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -20,7 +20,7 @@ abstract class CollectionReference extends Query { DocumentReference parent() { throw UnimplementedError("parent() is not implemented"); } - + /// Returns a `DocumentReference` with the provided path. /// /// If no [path] is provided, an auto-generated ID is used. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart index 77fd723cbd15..9efb650b1ba2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart @@ -8,7 +8,7 @@ part of cloud_firestore_platform_interface; /// to a subcollection. abstract class DocumentReference { DocumentReference(this.firestore, this._pathComponents); - + /// The Firestore instance associated with this document reference final FirestorePlatform firestore; final List _pathComponents; @@ -22,7 +22,8 @@ abstract class DocumentReference { /// Parent returns the containing [CollectionReference]. CollectionReference parent() { - final parentPathComponents = List.from(_pathComponents)..removeLast(); + final parentPathComponents = List.from(_pathComponents) + ..removeLast(); return firestore.collection( parentPathComponents.join("/"), ); @@ -60,7 +61,7 @@ abstract class DocumentReference { Future get({Source source = Source.serverAndCache}) async { throw UnimplementedError("get() is not implemented"); } - + /// Deletes the document referred to by this [DocumentReference]. Future delete() { throw UnimplementedError("delete() is not implemented"); @@ -78,4 +79,4 @@ abstract class DocumentReference { Stream snapshots({bool includeMetadataChanges = false}) { throw UnimplementedError("snapshots() is not implemented"); } -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 976526d2a824..1a8443d3d3b7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -7,7 +7,6 @@ part of cloud_firestore_platform_interface; /// A class to define an interface that's required /// for building platform-specific implementation abstract class FieldValueInterface { - /// Implementation instance FieldValueInterface get instance; @@ -20,15 +19,14 @@ abstract class FieldValueInterface { /// Mobile platform implementation for [FieldValueInterface] class FieldValue implements FieldValueInterface { - /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValue] static Map _serverDelegates(Map data) { Map output = Map.from(data); output.updateAll((key, value) { - if(value is FieldValueInterface && value.instance is FieldValue) { + if (value is FieldValueInterface && value.instance is FieldValue) { return value.instance; - } else{ + } else { return value; } }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index e63f168e480c..50f32d5d4d97 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -12,7 +12,6 @@ enum FieldValueType { } abstract class FieldValueFactory { - static FieldValueFactory get instance => _instance; static FieldValueFactory _instance = MethodChannelFieldValueFactory(); @@ -48,4 +47,4 @@ abstract class FieldValueFactory { /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. FieldValueInterface increment(num value); -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index cc6a4dbccf53..7c837d8cbc98 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -26,8 +26,10 @@ abstract class Query { /// Represents the components of the path referenced by `this` [Query] final List pathComponents; + /// Map of the parameters used for filtering and sorting documents final Map parameters; + /// Indicates if `this` [Query] is for a collection group final bool isCollectionGroup; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 67de0fca6842..9b54a6cc3c67 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -6,7 +6,6 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - QuerySnapshot(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index 4d78040ff37e..f696c22faabe 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -6,7 +6,8 @@ part of cloud_firestore_platform_interface; class Transaction extends TransactionPlatform { @visibleForTesting - Transaction(int transactionId, FirestorePlatform firestore) : super(transactionId, firestore); + Transaction(int transactionId, FirestorePlatform firestore) + : super(transactionId, firestore); Future finish() => Future.wait(_pendingResults); @@ -29,7 +30,7 @@ class Transaction extends TransactionPlatform { return null; } } - + @override Future _delete(DocumentReference documentReference) async { return MethodChannelFirestore.channel @@ -39,7 +40,7 @@ class Transaction extends TransactionPlatform { 'path': documentReference.path, }); } - + @override Future _update( DocumentReference documentReference, Map data) async { @@ -51,7 +52,7 @@ class Transaction extends TransactionPlatform { 'data': data, }); } - + @override Future _set( DocumentReference documentReference, Map data) async { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart index 3fd9e517af61..9b4ec5415867 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart @@ -13,7 +13,8 @@ part of cloud_firestore_platform_interface; class WriteBatch extends WriteBatchPlatform { WriteBatch(this._firestore) : _handle = MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#create', {'app': _firestore.appName()}), + 'WriteBatch#create', + {'app': _firestore.appName()}), super._(); final FirestorePlatform _firestore; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart index 5bd2e5ef9396..4a7043800174 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart @@ -12,8 +12,6 @@ part of cloud_firestore_platform_interface; /// nor can it be committed again. abstract class WriteBatchPlatform { WriteBatchPlatform._(); - - final List> _actions = >[]; /// Indicator to whether or not this [WriteBatch] has been committed. bool _committed = false; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 6d0049d8f49a..f495fb2259b3 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -48,7 +48,8 @@ void main() { collectionReference = firestore.collection('foo'); collectionGroupQuery = firestore.collectionGroup('bar'); transaction = Transaction(0, firestore); - MethodChannelFirestore.channel.setMockMethodCallHandler((MethodCall methodCall) async { + MethodChannelFirestore.channel + .setMockMethodCallHandler((MethodCall methodCall) async { log.add(methodCall); switch (methodCall.method) { case 'Query#addSnapshotListener': @@ -179,7 +180,8 @@ void main() { test('settings', () async { final FirebaseApp app = FirebaseApp(name: "testApp2"); - final MethodChannelFirestore firestoreWithSettings = MethodChannelFirestore(app: app); + final MethodChannelFirestore firestoreWithSettings = + MethodChannelFirestore(app: app); await firestoreWithSettings.settings( persistenceEnabled: true, host: null, @@ -384,7 +386,6 @@ void main() { ['createdAt', '<', 100], ], 'orderBy': >[], - }, 'includeMetadataChanges': false, }, @@ -460,7 +461,6 @@ void main() { ], ], 'orderBy': >[], - }, 'includeMetadataChanges': false, }, @@ -1149,12 +1149,17 @@ void main() { }); test('encode and decode FieldValue', () { - _checkEncodeDecode(codec, FieldValueFactory.instance.arrayUnion([123])); - _checkEncodeDecode(codec, FieldValueFactory.instance.arrayRemove([123])); + _checkEncodeDecode( + codec, FieldValueFactory.instance.arrayUnion([123])); + _checkEncodeDecode( + codec, FieldValueFactory.instance.arrayRemove([123])); _checkEncodeDecode(codec, FieldValueFactory.instance.delete()); - _checkEncodeDecode(codec, FieldValueFactory.instance.serverTimestamp()); - _checkEncodeDecode(codec, FieldValueFactory.instance.increment(1.0)); - _checkEncodeDecode(codec, FieldValueFactory.instance.increment(1)); + _checkEncodeDecode( + codec, FieldValueFactory.instance.serverTimestamp()); + _checkEncodeDecode( + codec, FieldValueFactory.instance.increment(1.0)); + _checkEncodeDecode( + codec, FieldValueFactory.instance.increment(1)); }); test('encode and decode FieldPath', () { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index fd5d489acf84..7b6167359454 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -11,7 +11,8 @@ class DocumentReferenceWeb extends DocumentReference { @override Future setData(Map data, {bool merge = false}) => - delegate.set(FieldValueWeb._serverDelegates(data), web.SetOptions(merge: merge)); + delegate.set( + FieldValueWeb._serverDelegates(data), web.SetOptions(merge: merge)); @override Future updateData(Map data) => diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 562ceb2d3bf4..34d4f265273b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -23,7 +23,12 @@ class FieldValueFactoryWeb implements FieldValueFactory { FieldValueInterface increment(num value) { assert(num is double || num is int, "value can only be double or int"); final delegate = web.FieldValue.increment(value); - return FieldValueWeb._(delegate, value is double ? FieldValueType.incrementDouble : FieldValueType.incrementDouble, value); + return FieldValueWeb._( + delegate, + value is double + ? FieldValueType.incrementDouble + : FieldValueType.incrementDouble, + value); } @override @@ -31,5 +36,4 @@ class FieldValueFactoryWeb implements FieldValueFactory { final delegate = web.FieldValue.serverTimestamp(); return FieldValueWeb._(delegate, FieldValueType.serverTimestamp, null); } - -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index 09ca10e57170..c850a7598f13 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -4,9 +4,9 @@ class FieldValueWeb implements FieldValueInterface, web.FieldValue { static Map _serverDelegates(Map data) { Map output = Map.from(data); output.updateAll((key, value) { - if(value is FieldValueInterface && value.instance is FieldValueWeb) { + if (value is FieldValueInterface && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb)._delegate; - } else{ + } else { return value; } }); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 9446dcd87c08..9d092e02a2ee 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -37,7 +37,7 @@ class FirestoreWeb extends FirestorePlatform { @override Query collectionGroup(String path) { - return QueryWeb(this, path,webFirestore.collectionGroup(path), + return QueryWeb(this, path, webFirestore.collectionGroup(path), isCollectionGroup: true); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 1cae21ce348a..2c2f4f6248d0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -31,18 +31,25 @@ class QueryWeb implements Query { isCollectionGroup: _isCollectionGroup); @override - Query endAtDocument(DocumentSnapshot documentSnapshot) => - QueryWeb(this._firestore, this._path, - _generateOrderByQuery(documentSnapshot).endAt(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); + Query endAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb( + this._firestore, + this._path, + _generateOrderByQuery(documentSnapshot) + .endAt(fieldValues: documentSnapshot.data.values), + isCollectionGroup: _isCollectionGroup); @override Query endBefore(List values) => QueryWeb(this._firestore, this._path, - webQuery != null ? webQuery.endBefore(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); + webQuery != null ? webQuery.endBefore(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup); @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - QueryWeb(this._firestore, this._path, - _generateOrderByQuery(documentSnapshot).endBefore(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); + Query endBeforeDocument(DocumentSnapshot documentSnapshot) => QueryWeb( + this._firestore, + this._path, + _generateOrderByQuery(documentSnapshot) + .endBefore(fieldValues: documentSnapshot.data.values), + isCollectionGroup: _isCollectionGroup); @override FirestorePlatform get firestore => _firestore; @@ -51,7 +58,12 @@ class QueryWeb implements Query { bool get isCollectionGroup => _isCollectionGroup; @override - Query limit(int length) => QueryWeb(this._firestore, this._path, webQuery != null ? webQuery.limit(length) : null,isCollectionGroup: _isCollectionGroup,); + Query limit(int length) => QueryWeb( + this._firestore, + this._path, + webQuery != null ? webQuery.limit(length) : null, + isCollectionGroup: _isCollectionGroup, + ); @override Query orderBy(field, {bool descending = false}) => QueryWeb( @@ -72,31 +84,32 @@ class QueryWeb implements Query { @override Query startAfter(List values) => QueryWeb( - this._firestore, - this._path, - webQuery.startAfter(fieldValues: values), - isCollectionGroup: _isCollectionGroup - ); + this._firestore, this._path, webQuery.startAfter(fieldValues: values), + isCollectionGroup: _isCollectionGroup); @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) => - QueryWeb(this._firestore, this._path, - _generateOrderByQuery(documentSnapshot) - .startAfter(fieldValues: documentSnapshot.data.values),isCollectionGroup: _isCollectionGroup); + Query startAfterDocument(DocumentSnapshot documentSnapshot) => QueryWeb( + this._firestore, + this._path, + _generateOrderByQuery(documentSnapshot) + .startAfter(fieldValues: documentSnapshot.data.values), + isCollectionGroup: _isCollectionGroup); @override Query startAt(List values) => QueryWeb( this._firestore, this._path, - webQuery.startAt(fieldValues: values) , + webQuery.startAt(fieldValues: values), isCollectionGroup: _isCollectionGroup, ); @override - Query startAtDocument(DocumentSnapshot documentSnapshot) => - QueryWeb(this._firestore, this._path, - _generateOrderByQuery(documentSnapshot) - .startAt(fieldValues: documentSnapshot.data.values), isCollectionGroup: _isCollectionGroup); + Query startAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb( + this._firestore, + this._path, + _generateOrderByQuery(documentSnapshot) + .startAt(fieldValues: documentSnapshot.data.values), + isCollectionGroup: _isCollectionGroup); @override Query where(field, @@ -150,7 +163,8 @@ class QueryWeb implements Query { 'Use isEqualTo to filter on non-null values.'); query = query.where(field, "==", null); } - return QueryWeb(this._firestore, this._path, query, isCollectionGroup: _isCollectionGroup); + return QueryWeb(this._firestore, this._path, query, + isCollectionGroup: _isCollectionGroup); } QuerySnapshot _webQuerySnapshotToQuerySnapshot( diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 27590249ec19..43c8a9f9e376 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -10,40 +10,47 @@ class TransactionWeb implements Transaction { @override Future delete(DocumentReference documentReference) async { assert(documentReference is DocumentReferenceWeb); - await _webTransaction.delete((documentReference as DocumentReferenceWeb).delegate); + await _webTransaction + .delete((documentReference as DocumentReferenceWeb).delegate); } @override Future get(DocumentReference documentReference) async { assert(documentReference is DocumentReferenceWeb); - final webSnapshot = await _webTransaction.get((documentReference as DocumentReferenceWeb).delegate); + final webSnapshot = await _webTransaction + .get((documentReference as DocumentReferenceWeb).delegate); return _fromWeb(webSnapshot); } @override - Future set(DocumentReference documentReference, Map data) async { + Future set( + DocumentReference documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); - await _webTransaction.set((documentReference as DocumentReferenceWeb).delegate, data); + await _webTransaction.set( + (documentReference as DocumentReferenceWeb).delegate, data); } @override - Future update(DocumentReference documentReference, Map data) async { + Future update( + DocumentReference documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); - await _webTransaction.update((documentReference as DocumentReferenceWeb).delegate, data: data); + await _webTransaction.update( + (documentReference as DocumentReferenceWeb).delegate, + data: data); } - DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( - webSnapshot.ref.path, - webSnapshot.data(), - SnapshotMetadata( - webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache, - ), - this.firestore); + DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => + DocumentSnapshot( + webSnapshot.ref.path, + webSnapshot.data(), + SnapshotMetadata( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + this.firestore); @override Future finish() { return Future.value(); } - -} \ No newline at end of file +} From dc3e4cc9976280229b2b172e4a610a123f9dfc4a Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 11:09:33 +0000 Subject: [PATCH 039/144] Fix message codec to run transaction on mobile --- .../lib/src/firestore_message_codec.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index a29753e18985..3397ea50b653 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -61,7 +61,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putUint8(_kBlob); writeSize(buffer, value.bytes.length); buffer.putUint8List(value.bytes); - } else if (value is FieldValue) { + } else if (value is FieldValueInterface) { final int code = _kFieldValueCodes[value.type]; assert(code != null); buffer.putUint8(code); From b7cb9a37fc3ad6a897c70af0c9ccfe022664886b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 11:41:48 +0000 Subject: [PATCH 040/144] Fix transaction writes on mobile and web - use field value serve delegates - rely on delegated document references --- .../cloud_firestore/lib/src/transaction.dart | 17 ++++------------- .../cloud_firestore_web/lib/firestore_web.dart | 7 ++++--- .../lib/transaction_web.dart | 4 ++-- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 8e1158ebf1ba..e0ed46122e27 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -16,9 +16,7 @@ class Transaction { /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReference documentReference) async { - final result = await _delegate.get(platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/"))); + final result = await _delegate.get(documentReference._delegate); if (result != null) { return DocumentSnapshot._(result); } else { @@ -31,9 +29,7 @@ class Transaction { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future delete(DocumentReference documentReference) { - return _delegate.delete(platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/"))); + return _delegate.delete(documentReference._delegate); } /// Updates fields in the document referred to by [documentReference]. @@ -44,9 +40,7 @@ class Transaction { Future update( DocumentReference documentReference, Map data) async { return _delegate.update( - platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/")), + documentReference._delegate, data); } @@ -58,10 +52,7 @@ class Transaction { /// when the transaction handler completes. Future set( DocumentReference documentReference, Map data) { - return _delegate.set( - platform.MethodChannelDocumentReference( - platform.FirestorePlatform.instance, - documentReference.path.split("/")), + return _delegate.set(documentReference._delegate, data); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 9d092e02a2ee..3de32d03f309 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -70,10 +70,11 @@ class FirestoreWeb extends FirestorePlatform { @override Future> runTransaction( TransactionHandler transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) { - return webFirestore.runTransaction((transaction) { - transactionHandler(TransactionWeb._(transaction, this)); + {Duration timeout = const Duration(seconds: 5)}) async { + await webFirestore.runTransaction((transaction) async { + return await transactionHandler(TransactionWeb._(transaction, this)); }).timeout(timeout); + return {}; } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 43c8a9f9e376..30f24e010b6c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -27,7 +27,7 @@ class TransactionWeb implements Transaction { DocumentReference documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( - (documentReference as DocumentReferenceWeb).delegate, data); + (documentReference as DocumentReferenceWeb).delegate, FieldValueWeb._serverDelegates(data)); } @override @@ -36,7 +36,7 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, - data: data); + data: FieldValueWeb._serverDelegates(data)); } DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => From 05584ed957065bab8aa9afe5c07f38a7e63830be Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 11:47:22 +0000 Subject: [PATCH 041/144] Updated example to showcase transactions --- .../cloud_firestore/example/lib/main.dart | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index 9b1954d0a0f8..7e072c230185 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -33,7 +33,7 @@ class MessageList extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder( - stream: firestore.collection('messages').snapshots(), + stream: firestore.collection("messages").orderBy("created_at", descending: true).snapshots(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (!snapshot.hasData) return const Text('Loading...'); final int messageCount = snapshot.data.documents.length; @@ -69,11 +69,43 @@ class MyHomePage extends StatelessWidget { }); } + Future _runTransaction() async { + firestore.runTransaction((Transaction transaction) async { + final allDocs = await firestore.collection("messages").getDocuments(); + final toBeRetrieved = allDocs.documents.sublist(allDocs.documents.length ~/ 2); + final toBeDeleted = allDocs.documents.sublist(0, allDocs.documents.length ~/ 2); + await Future.forEach(toBeDeleted, (DocumentSnapshot snapshot) async { + await transaction.delete(snapshot.reference); + }); + + await Future.forEach(toBeRetrieved, (DocumentSnapshot snapshot) async { + await transaction.update(snapshot.reference, { + "message": "Updated from Transaction", + "created_at": FieldValue.serverTimestamp() + }); + }); + }); + + await Future.forEach(List.generate(2, (index) => index), (item) async { + await firestore.runTransaction((Transaction transaction) async { + await Future.forEach(List.generate(10, (index) => index), (item) async { + await transaction.set(firestore.collection("messages").document(), { + "message": "Created from Transaction $item", + "created_at": FieldValue.serverTimestamp() + }); + }); + }); + }); + } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Firestore Example'), + actions: [ + FlatButton(onPressed: _runTransaction, child: Text("Run Transaction"),) + ], ), body: MessageList(firestore: firestore), floatingActionButton: FloatingActionButton( From b74bd770c61a5438b55eb2274398f62fca18af20 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 12:00:28 +0000 Subject: [PATCH 042/144] PR feedback fixes --- .../lib/field_value_factory_web.dart | 2 +- .../cloud_firestore_web/lib/query_web.dart | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 34d4f265273b..0cd65b7e1a93 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -21,7 +21,7 @@ class FieldValueFactoryWeb implements FieldValueFactory { @override FieldValueInterface increment(num value) { - assert(num is double || num is int, "value can only be double or int"); + assert(value is double || value is int, "value can only be double or int"); final delegate = web.FieldValue.increment(value); return FieldValueWeb._( delegate, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 2c2f4f6248d0..489ef25b1419 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -6,6 +6,10 @@ class QueryWeb implements Query { final bool _isCollectionGroup; final String _path; + static const _changeTypeAdded = "added"; + static const _changeTypeModified = "modified"; + static const _changeTypeRemoved = "removed"; + QueryWeb(this._firestore, this._path, this.webQuery, {bool isCollectionGroup}) : this._isCollectionGroup = isCollectionGroup ?? false; @@ -185,11 +189,11 @@ class QueryWeb implements Query { DocumentChangeType _fromString(String item) { switch (item.toLowerCase()) { - case "added": + case _changeTypeAdded: return DocumentChangeType.added; - case "modified": + case _changeTypeModified: return DocumentChangeType.modified; - case "removed": + case _changeTypeRemoved: return DocumentChangeType.removed; default: throw ArgumentError("Invalid type"); From 0e261aaaaef414f5ac418bcc0375fb596ec735cc Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 12:54:25 +0000 Subject: [PATCH 043/144] Added write batch support - Added button in example --- .../cloud_firestore/example/lib/main.dart | 14 +++++++- .../cloud_firestore/lib/src/firestore.dart | 2 +- .../cloud_firestore/lib/src/write_batch.dart | 25 ++++++------- .../lib/firestore_web.dart | 3 +- .../lib/write_batch_web.dart | 35 +++++++++++++++++++ 5 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index 7e072c230185..478c1e11f2ac 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -98,13 +98,25 @@ class MyHomePage extends StatelessWidget { }); } + Future _runBatchWrite() async { + final batchWrite = firestore.batch(); + final querySnapshot = await firestore.collection("messages").orderBy("created_at").limit(10).getDocuments(); + querySnapshot.documents.forEach((DocumentSnapshot doc){ + batchWrite.updateData(doc.reference, {"message":"Batched message", "created_at": FieldValue.serverTimestamp()}); + }); + batchWrite.setData(firestore.collection("messages").document(), {"message":"Batched message created", "created_at": FieldValue.serverTimestamp()}); + batchWrite.delete(querySnapshot.documents[querySnapshot.documents.length - 2].reference); + batchWrite.delete(querySnapshot.documents.last.reference); + await batchWrite.commit(); + } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Firestore Example'), actions: [ - FlatButton(onPressed: _runTransaction, child: Text("Run Transaction"),) + FlatButton(onPressed: _runTransaction, child: Text("Run Transaction"),), + FlatButton(onPressed: _runBatchWrite, child: Text("Batch Write"),) ], ), body: MessageList(firestore: firestore), diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 0b1cc9e7854c..1d32061e0bd4 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -20,7 +20,7 @@ class Firestore { String appName() => _delegate.appName(); - WriteBatch batch() => WriteBatch._(); + WriteBatch batch() => WriteBatch._(_delegate.batch()); CollectionReference collection(String path) { assert(path != null); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 849e7eb417b5..76519165c353 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -10,25 +10,20 @@ part of cloud_firestore; /// /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. -class WriteBatch implements platform.WriteBatchPlatform { - platform.WriteBatch _delegate; - WriteBatch._() - : _delegate = platform.WriteBatch(platform.FirestorePlatform.instance); - @override +class WriteBatch { + final platform.WriteBatch _delegate; + WriteBatch._(this._delegate); + Future commit() => _delegate.commit(); - @override - void delete(platform.DocumentReference document) => - _delegate.delete(document); + void delete(DocumentReference document) => + _delegate.delete(document._delegate); - @override - void setData(platform.DocumentReference document, Map data, + void setData(DocumentReference document, Map data, {bool merge = false}) => - _delegate.setData(document, data, merge: merge); + _delegate.setData(document._delegate, data, merge: merge); - @override - void updateData( - platform.DocumentReference document, Map data) => - _delegate.updateData(document, data); + void updateData(DocumentReference document, Map data) => + _delegate.updateData(document._delegate, data); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 3de32d03f309..23cacdfbe860 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -13,6 +13,7 @@ part 'document_reference_web.dart'; part 'query_web.dart'; part 'transaction_web.dart'; part 'field_value_web.dart'; +part 'write_batch_web.dart'; class FirestoreWeb extends FirestorePlatform { final Firestore webFirestore; @@ -46,7 +47,7 @@ class FirestoreWeb extends FirestorePlatform { DocumentReferenceWeb(webFirestore, this, path.split('/')); @override - WriteBatch batch() => WriteBatch(this); + WriteBatch batch() => WriteBatchWeb._(webFirestore.batch()); @override Future enablePersistence(bool enable) async { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart new file mode 100644 index 000000000000..8e886e632564 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -0,0 +1,35 @@ +part of cloud_firestore_web; + +class WriteBatchWeb implements WriteBatch { + final web.WriteBatch _delegate; + + WriteBatchWeb._(this._delegate); + + @override + Future commit() async { + await _delegate.commit(); + } + + @override + void delete(DocumentReference document) { + assert(document is DocumentReferenceWeb); + _delegate.delete((document as DocumentReferenceWeb).delegate); + } + + @override + void setData(DocumentReference document, Map data, + {bool merge = false}) { + assert(document is DocumentReferenceWeb); + _delegate.set( + (document as DocumentReferenceWeb).delegate, + FieldValueWeb._serverDelegates(data), + merge ? web.SetOptions(merge: merge) : null); + } + + @override + void updateData(DocumentReference document, Map data) { + assert(document is DocumentReferenceWeb); + _delegate.set((document as DocumentReferenceWeb).delegate, + FieldValueWeb._serverDelegates(data)); + } +} From d73dccecd7a1f73abc07c3d97026e56f676906e0 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 13:10:36 +0000 Subject: [PATCH 044/144] Formatting --- .../cloud_firestore/example/lib/main.dart | 43 ++++++++++++++----- .../cloud_firestore/lib/src/transaction.dart | 7 +-- .../cloud_firestore/lib/src/write_batch.dart | 2 +- .../lib/firestore_web.dart | 2 +- .../lib/transaction_web.dart | 3 +- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index 478c1e11f2ac..345d7f606c05 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -33,7 +33,10 @@ class MessageList extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder( - stream: firestore.collection("messages").orderBy("created_at", descending: true).snapshots(), + stream: firestore + .collection("messages") + .orderBy("created_at", descending: true) + .snapshots(), builder: (BuildContext context, AsyncSnapshot snapshot) { if (!snapshot.hasData) return const Text('Loading...'); final int messageCount = snapshot.data.documents.length; @@ -72,8 +75,10 @@ class MyHomePage extends StatelessWidget { Future _runTransaction() async { firestore.runTransaction((Transaction transaction) async { final allDocs = await firestore.collection("messages").getDocuments(); - final toBeRetrieved = allDocs.documents.sublist(allDocs.documents.length ~/ 2); - final toBeDeleted = allDocs.documents.sublist(0, allDocs.documents.length ~/ 2); + final toBeRetrieved = + allDocs.documents.sublist(allDocs.documents.length ~/ 2); + final toBeDeleted = + allDocs.documents.sublist(0, allDocs.documents.length ~/ 2); await Future.forEach(toBeDeleted, (DocumentSnapshot snapshot) async { await transaction.delete(snapshot.reference); }); @@ -100,23 +105,41 @@ class MyHomePage extends StatelessWidget { Future _runBatchWrite() async { final batchWrite = firestore.batch(); - final querySnapshot = await firestore.collection("messages").orderBy("created_at").limit(10).getDocuments(); - querySnapshot.documents.forEach((DocumentSnapshot doc){ - batchWrite.updateData(doc.reference, {"message":"Batched message", "created_at": FieldValue.serverTimestamp()}); + final querySnapshot = await firestore + .collection("messages") + .orderBy("created_at") + .limit(10) + .getDocuments(); + querySnapshot.documents.forEach((DocumentSnapshot doc) { + batchWrite.updateData(doc.reference, { + "message": "Batched message", + "created_at": FieldValue.serverTimestamp() + }); + }); + batchWrite.setData(firestore.collection("messages").document(), { + "message": "Batched message created", + "created_at": FieldValue.serverTimestamp() }); - batchWrite.setData(firestore.collection("messages").document(), {"message":"Batched message created", "created_at": FieldValue.serverTimestamp()}); - batchWrite.delete(querySnapshot.documents[querySnapshot.documents.length - 2].reference); + batchWrite.delete( + querySnapshot.documents[querySnapshot.documents.length - 2].reference); batchWrite.delete(querySnapshot.documents.last.reference); await batchWrite.commit(); } + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Firestore Example'), actions: [ - FlatButton(onPressed: _runTransaction, child: Text("Run Transaction"),), - FlatButton(onPressed: _runBatchWrite, child: Text("Batch Write"),) + FlatButton( + onPressed: _runTransaction, + child: Text("Run Transaction"), + ), + FlatButton( + onPressed: _runBatchWrite, + child: Text("Batch Write"), + ) ], ), body: MessageList(firestore: firestore), diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index e0ed46122e27..2356ea89b910 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -39,9 +39,7 @@ class Transaction { /// when the transaction handler completes. Future update( DocumentReference documentReference, Map data) async { - return _delegate.update( - documentReference._delegate, - data); + return _delegate.update(documentReference._delegate, data); } /// Writes to the document referred to by the provided [DocumentReference]. @@ -52,7 +50,6 @@ class Transaction { /// when the transaction handler completes. Future set( DocumentReference documentReference, Map data) { - return _delegate.set(documentReference._delegate, - data); + return _delegate.set(documentReference._delegate, data); } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 76519165c353..a9fcb32d575e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -11,7 +11,7 @@ part of cloud_firestore; /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. -class WriteBatch { +class WriteBatch { final platform.WriteBatch _delegate; WriteBatch._(this._delegate); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 23cacdfbe860..934e8aa1be7b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -75,7 +75,7 @@ class FirestoreWeb extends FirestorePlatform { await webFirestore.runTransaction((transaction) async { return await transactionHandler(TransactionWeb._(transaction, this)); }).timeout(timeout); - return {}; + return {}; } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 30f24e010b6c..322da62b85b8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -27,7 +27,8 @@ class TransactionWeb implements Transaction { DocumentReference documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( - (documentReference as DocumentReferenceWeb).delegate, FieldValueWeb._serverDelegates(data)); + (documentReference as DocumentReferenceWeb).delegate, + FieldValueWeb._serverDelegates(data)); } @override From 0bfd69197211d50ad042abe34214a64d934cabb0 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 13:36:44 +0000 Subject: [PATCH 045/144] Fix write batch examples --- .../cloud_firestore/example/lib/main.dart | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index 345d7f606c05..34bffa9cb9f2 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -46,6 +46,10 @@ class MessageList extends StatelessWidget { final DocumentSnapshot document = snapshot.data.documents[index]; final dynamic message = document['message']; return ListTile( + trailing: IconButton( + onPressed: () => document.reference.delete(), + icon: Icon(Icons.delete), + ), title: Text( message != null ? message.toString() : '', ), @@ -108,9 +112,11 @@ class MyHomePage extends StatelessWidget { final querySnapshot = await firestore .collection("messages") .orderBy("created_at") - .limit(10) + .limit(12) .getDocuments(); - querySnapshot.documents.forEach((DocumentSnapshot doc) { + querySnapshot.documents + .sublist(0, querySnapshot.documents.length - 3) + .forEach((DocumentSnapshot doc) { batchWrite.updateData(doc.reference, { "message": "Batched message", "created_at": FieldValue.serverTimestamp() From 3c7faa06a4670651e2527ab5223f9b0982c2b7ca Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 14:26:46 +0000 Subject: [PATCH 046/144] Added comments to match existing API level documentation --- .../cloud_firestore/lib/src/firestore.dart | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 1d32061e0bd4..a179071f1ddb 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -15,21 +15,35 @@ class Firestore { static MethodChannel get channel => platform.MethodChannelFirestore.channel; + /// Gets the instance of Firestore for the default Firebase app. static Firestore get instance => Firestore(delegate: platform.FirestorePlatform.instance); + /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. + /// + /// If null, the default [FirebaseApp] is used. + FirebaseApp get app => _delegate.app; + String appName() => _delegate.appName(); + /// Creates a write batch, used for performing multiple writes as a single + /// atomic operation. + /// + /// Unlike transactions, write batches are persisted offline and therefore are + /// preferable when you don’t need to condition your writes on read data. WriteBatch batch() => WriteBatch._(_delegate.batch()); + /// Gets a [CollectionReference] for the specified Firestore path. CollectionReference collection(String path) { assert(path != null); return CollectionReference._(_delegate.collection(path)); } + /// Gets a [Query] for the specified collection group. Query collectionGroup(String path) => Query._(_delegate.collectionGroup(path)); + /// Gets a [DocumentReference] for the specified Firestore path. DocumentReference document(String path) => DocumentReference._(_delegate.document(path)); @@ -37,6 +51,27 @@ class Firestore { Future enablePersistence(bool enable) => _delegate.enablePersistence(enable); + /// Executes the given TransactionHandler and then attempts to commit the + /// changes applied within an atomic transaction. + /// + /// In the TransactionHandler, a set of reads and writes can be performed + /// atomically using the Transaction object passed to the TransactionHandler. + /// After the TransactionHandler is run, Firestore will attempt to apply the + /// changes to the server. If any of the data read has been modified outside + /// of this transaction since being read, then the transaction will be + /// retried by executing the updateBlock again. If the transaction still + /// fails after 5 retries, then the transaction will fail. + /// + /// The TransactionHandler may be executed multiple times, it should be able + /// to handle multiple executions. + /// + /// Data accessed with the transaction will not reflect local changes that + /// have not been committed. For this reason, it is required that all + /// reads are performed before any writes. Transactions must be performed + /// while online. Otherwise, reads will fail, and the final commit will fail. + /// + /// By default transactions are limited to 5 seconds of execution time. This + /// timeout can be adjusted by setting the timeout parameter. Future> runTransaction( TransactionHandler transactionHandler, {Duration timeout = const Duration(seconds: 5)}) { From dab85d29cdc18cf44e3e308f89f979e0adb9bb46 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 14:38:29 +0000 Subject: [PATCH 047/144] Avoid setting host and ssl if either is null --- .../lib/firestore_web.dart | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 934e8aa1be7b..6c781e31fc3f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -8,11 +8,17 @@ import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; part 'collection_reference_web.dart'; + part 'field_value_factory_web.dart'; + part 'document_reference_web.dart'; + part 'query_web.dart'; + part 'transaction_web.dart'; + part 'field_value_web.dart'; + part 'write_batch_web.dart'; class FirestoreWeb extends FirestorePlatform { @@ -62,10 +68,18 @@ class FirestoreWeb extends FirestorePlatform { String host, bool sslEnabled, int cacheSizeBytes}) async { - return Future.sync(() { + if (host != null && sslEnabled != null) { webFirestore.settings(Settings( - ssl: sslEnabled, cacheSizeBytes: cacheSizeBytes, host: host)); - }); + cacheSizeBytes: cacheSizeBytes ?? 40000000, + host: host, + ssl: sslEnabled)); + } else { + webFirestore + .settings(Settings(cacheSizeBytes: cacheSizeBytes ?? 40000000)); + } + if (persistenceEnabled) { + await webFirestore.enablePersistence(); + } } @override From b23805c91810e851873da6c4edf7880f63b40282 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 16:30:47 +0000 Subject: [PATCH 048/144] Bug fixes for QueryWeb and CollectionWeb --- .../cloud_firestore/lib/cloud_firestore.dart | 4 +- .../cloud_firestore/lib/src/field_path.dart | 21 --- .../lib/collection_reference_web.dart | 102 +++++++++----- .../lib/firestore_web.dart | 5 +- .../cloud_firestore_web/lib/query_web.dart | 130 +++++++++++------- 5 files changed, 151 insertions(+), 111 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/field_path.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 95342d193382..85fac8b908dd 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -16,13 +16,15 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; +export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' + show FieldPath; + part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; part 'src/utils/platform_utils.dart'; part 'src/document_reference.dart'; part 'src/document_snapshot.dart'; -part 'src/field_path.dart'; part 'src/field_value.dart'; part 'src/firestore.dart'; part 'src/geo_point.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_path.dart deleted file mode 100644 index 64cdde8fad31..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_path.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -enum _FieldPathType { - documentId, -} - -/// A [FieldPath] refers to a field in a document. -class FieldPath { - const FieldPath._(this.type); - - @visibleForTesting - final _FieldPathType type; - - /// The path to the document id, which can be used in queries. - static FieldPath get documentId => - const FieldPath._(_FieldPathType.documentId); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 35a88c069caa..c529d4931b14 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -4,7 +4,7 @@ class CollectionReferenceWeb implements CollectionReference { final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; final List pathComponents; - final QueryWeb _queryDelegate; + QueryWeb _queryDelegate; CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) @@ -50,18 +50,28 @@ class CollectionReferenceWeb implements CollectionReference { Map buildArguments() => _queryDelegate.buildArguments(); @override - Query endAt(List values) => _queryDelegate.endAt(values); + Query endAt(List values) { + _resetQueryDelegate(); + return _queryDelegate.endAt(values); + } @override - Query endAtDocument(DocumentSnapshot documentSnapshot) => - _queryDelegate.endAtDocument(documentSnapshot); + Query endAtDocument(DocumentSnapshot documentSnapshot) { + _resetQueryDelegate(); + return _queryDelegate.endAtDocument(documentSnapshot); + } @override - Query endBefore(List values) => _queryDelegate.endBefore(values); + Query endBefore(List values) { + _resetQueryDelegate(); + return _queryDelegate.endBefore(values); + } @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - _queryDelegate.endBeforeDocument(documentSnapshot); + Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + _resetQueryDelegate(); + return _queryDelegate.endBeforeDocument(documentSnapshot); + } @override FirestorePlatform get firestore => _firestorePlatform; @@ -77,11 +87,16 @@ class CollectionReferenceWeb implements CollectionReference { bool get isCollectionGroup => false; @override - Query limit(int length) => _queryDelegate.limit(length); + Query limit(int length) { + _resetQueryDelegate(); + return _queryDelegate.limit(length); + } @override - Query orderBy(field, {bool descending = false}) => - _queryDelegate.orderBy(field, descending: descending); + Query orderBy(field, {bool descending = false}) { + _resetQueryDelegate(); + return _queryDelegate.orderBy(field, descending: descending); + } @override Map get parameters => _queryDelegate.parameters; @@ -97,38 +112,55 @@ class CollectionReferenceWeb implements CollectionReference { _queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); @override - Query startAfter(List values) => _queryDelegate.startAfter(values); + Query startAfter(List values) { + _resetQueryDelegate(); + return _queryDelegate.startAfter(values); + } @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) => - _queryDelegate.startAfterDocument(documentSnapshot); + Query startAfterDocument(DocumentSnapshot documentSnapshot) { + _resetQueryDelegate(); + return _queryDelegate.startAfterDocument(documentSnapshot); + } @override - Query startAt(List values) => _queryDelegate.startAt(values); + Query startAt(List values) { + _resetQueryDelegate(); + return _queryDelegate.startAt(values); + } @override - Query startAtDocument(DocumentSnapshot documentSnapshot) => - _queryDelegate.startAtDocument(documentSnapshot); + Query startAtDocument(DocumentSnapshot documentSnapshot) { + _resetQueryDelegate(); + return _queryDelegate.startAtDocument(documentSnapshot); + } @override Query where(field, - {isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull}) => - _queryDelegate.where(field, - isEqualTo: isEqualTo, - isLessThan: isLessThan, - isLessThanOrEqualTo: isLessThanOrEqualTo, - isGreaterThan: isGreaterThan, - isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, - arrayContains: arrayContains, - arrayContainsAny: arrayContainsAny, - whereIn: whereIn, - isNull: isNull); + {isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull}) { + _resetQueryDelegate(); + return _queryDelegate.where(field, + isEqualTo: isEqualTo, + isLessThan: isLessThan, + isLessThanOrEqualTo: isLessThanOrEqualTo, + isGreaterThan: isGreaterThan, + isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, + arrayContains: arrayContains, + arrayContainsAny: arrayContainsAny, + whereIn: whereIn, + isNull: isNull); + } + + void _resetQueryDelegate() { + _queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), + webFirestore.collection(pathComponents.join("/"))); + } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 6c781e31fc3f..b1cdb136fd8f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -86,10 +86,11 @@ class FirestoreWeb extends FirestorePlatform { Future> runTransaction( TransactionHandler transactionHandler, {Duration timeout = const Duration(seconds: 5)}) async { + Map result; await webFirestore.runTransaction((transaction) async { - return await transactionHandler(TransactionWeb._(transaction, this)); + result = await transactionHandler(TransactionWeb._(transaction, this)); }).timeout(timeout); - return {}; + return result is Map ? result : {}; } @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 489ef25b1419..411d4267f92f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -5,13 +5,15 @@ class QueryWeb implements Query { final FirestorePlatform _firestore; final bool _isCollectionGroup; final String _path; - + final List _orderByKeys; static const _changeTypeAdded = "added"; static const _changeTypeModified = "modified"; static const _changeTypeRemoved = "removed"; - QueryWeb(this._firestore, this._path, this.webQuery, {bool isCollectionGroup}) - : this._isCollectionGroup = isCollectionGroup ?? false; + QueryWeb(this._firestore, this._path, this.webQuery, + {bool isCollectionGroup, List orderByKeys}) + : this._isCollectionGroup = isCollectionGroup ?? false, + this._orderByKeys = orderByKeys ?? []; @override Stream snapshots({bool includeMetadataChanges = false}) { @@ -35,12 +37,16 @@ class QueryWeb implements Query { isCollectionGroup: _isCollectionGroup); @override - Query endAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb( - this._firestore, - this._path, - _generateOrderByQuery(documentSnapshot) - .endAt(fieldValues: documentSnapshot.data.values), - isCollectionGroup: _isCollectionGroup); + Query endAtDocument(DocumentSnapshot documentSnapshot) { + assert(webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + webQuery.endAt( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + isCollectionGroup: _isCollectionGroup); + } @override Query endBefore(List values) => QueryWeb(this._firestore, this._path, @@ -48,12 +54,16 @@ class QueryWeb implements Query { isCollectionGroup: _isCollectionGroup); @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) => QueryWeb( - this._firestore, - this._path, - _generateOrderByQuery(documentSnapshot) - .endBefore(fieldValues: documentSnapshot.data.values), - isCollectionGroup: _isCollectionGroup); + Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + assert(webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + webQuery.endBefore( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + isCollectionGroup: _isCollectionGroup); + } @override FirestorePlatform get firestore => _firestore; @@ -66,16 +76,24 @@ class QueryWeb implements Query { this._firestore, this._path, webQuery != null ? webQuery.limit(length) : null, + orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup, ); @override - Query orderBy(field, {bool descending = false}) => QueryWeb( - this._firestore, - this._path, - webQuery.orderBy(field, descending ? "desc" : "asc"), - isCollectionGroup: _isCollectionGroup, - ); + Query orderBy(field, {bool descending = false}) { + dynamic usableField = field; + if (field == FieldPath.documentId) { + usableField = web.FieldPath.documentId(); + } + return QueryWeb( + this._firestore, + this._path, + webQuery.orderBy(usableField, descending ? "desc" : "asc"), + orderByKeys: _orderByKeys..add(usableField), + isCollectionGroup: _isCollectionGroup, + ); + } @override String get path => this._path; @@ -89,31 +107,42 @@ class QueryWeb implements Query { @override Query startAfter(List values) => QueryWeb( this._firestore, this._path, webQuery.startAfter(fieldValues: values), - isCollectionGroup: _isCollectionGroup); + orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) => QueryWeb( - this._firestore, - this._path, - _generateOrderByQuery(documentSnapshot) - .startAfter(fieldValues: documentSnapshot.data.values), - isCollectionGroup: _isCollectionGroup); + Query startAfterDocument(DocumentSnapshot documentSnapshot) { + assert(webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + webQuery.startAfter( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup); + } @override Query startAt(List values) => QueryWeb( this._firestore, this._path, webQuery.startAt(fieldValues: values), + orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup, ); @override - Query startAtDocument(DocumentSnapshot documentSnapshot) => QueryWeb( - this._firestore, - this._path, - _generateOrderByQuery(documentSnapshot) - .startAt(fieldValues: documentSnapshot.data.values), - isCollectionGroup: _isCollectionGroup); + Query startAtDocument(DocumentSnapshot documentSnapshot) { + assert(webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + webQuery.startAt( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup); + } @override Query where(field, @@ -129,46 +158,50 @@ class QueryWeb implements Query { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); assert(webQuery != null); - + dynamic usableField = field; + ; + if (field == FieldPath.documentId) { + usableField = web.FieldPath.documentId(); + } web.Query query = webQuery; if (isEqualTo != null) { - query = query.where(field, "==", isEqualTo); + query = query.where(usableField, "==", isEqualTo); } if (isLessThan != null) { - query = query.where(field, "<", isLessThan); + query = query.where(usableField, "<", isLessThan); } if (isLessThanOrEqualTo != null) { - query = query.where(field, "<=", isLessThanOrEqualTo); + query = query.where(usableField, "<=", isLessThanOrEqualTo); } if (isGreaterThan != null) { - query = query.where(field, ">", isGreaterThan); + query = query.where(usableField, ">", isGreaterThan); } if (isGreaterThanOrEqualTo != null) { - query = query.where(field, ">=", isGreaterThanOrEqualTo); + query = query.where(usableField, ">=", isGreaterThanOrEqualTo); } if (arrayContains != null) { - query = query.where(field, "array-contains", arrayContains); + query = query.where(usableField, "array-contains", arrayContains); } if (arrayContainsAny != null) { assert(arrayContainsAny.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(field, "array-contains-any", arrayContainsAny); + query = query.where(usableField, "array-contains-any", arrayContainsAny); } if (whereIn != null) { assert( whereIn.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(field, "in", whereIn); + query = query.where(usableField, "in", whereIn); } if (isNull != null) { assert( isNull, 'isNull can only be set to true. ' 'Use isEqualTo to filter on non-null values.'); - query = query.where(field, "==", null); + query = query.where(usableField, "==", null); } return QueryWeb(this._firestore, this._path, query, - isCollectionGroup: _isCollectionGroup); + orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); } QuerySnapshot _webQuerySnapshotToQuerySnapshot( @@ -210,13 +243,6 @@ class QueryWeb implements Query { this._firestore); } - web.Query _generateOrderByQuery(DocumentSnapshot webSnapshot) { - assert(webQuery != null); - web.Query query = webQuery; - webSnapshot.data.keys.forEach((key) => query = query.orderBy(key)); - return query; - } - SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { return SnapshotMetadata( webMetadata.hasPendingWrites, webMetadata.fromCache); From 6632ae73e211b35e22c2fda5f88edddb4edf5974 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 17:01:31 +0000 Subject: [PATCH 049/144] Added support for handling Blob and GeoPoint --- .../cloud_firestore/lib/cloud_firestore.dart | 6 +--- .../cloud_firestore/lib/src/blob.dart | 19 ----------- .../cloud_firestore/lib/src/geo_point.dart | 19 ----------- .../lib/document_reference_web.dart | 6 ++-- .../lib/field_value_web.dart | 12 ------- .../lib/firestore_web.dart | 2 ++ .../lib/transaction_web.dart | 6 ++-- .../lib/utils/codec_utility.dart | 33 +++++++++++++++++++ .../lib/write_batch_web.dart | 4 +-- 9 files changed, 44 insertions(+), 63 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/blob.dart delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/geo_point.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 85fac8b908dd..0216eaa12cb0 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -5,21 +5,18 @@ library cloud_firestore; import 'dart:async'; -import 'dart:typed_data'; import 'dart:ui' show hashValues, hashList; import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; -import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' - show FieldPath; + show FieldPath, Blob, GeoPoint; -part 'src/blob.dart'; part 'src/collection_reference.dart'; part 'src/document_change.dart'; part 'src/utils/platform_utils.dart'; @@ -27,7 +24,6 @@ part 'src/document_reference.dart'; part 'src/document_snapshot.dart'; part 'src/field_value.dart'; part 'src/firestore.dart'; -part 'src/geo_point.dart'; part 'src/query.dart'; part 'src/query_snapshot.dart'; part 'src/snapshot_metadata.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore/lib/src/blob.dart deleted file mode 100644 index 665efead5622..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/blob.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -class Blob { - const Blob(this.bytes); - - final Uint8List bytes; - - @override - bool operator ==(dynamic other) => - other is Blob && - const DeepCollectionEquality().equals(other.bytes, bytes); - - @override - int get hashCode => hashList(bytes); -} diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore/lib/src/geo_point.dart deleted file mode 100644 index bc91d4d16712..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/geo_point.dart +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -class GeoPoint { - const GeoPoint(this.latitude, this.longitude); - - final double latitude; - final double longitude; - - @override - bool operator ==(dynamic o) => - o is GeoPoint && o.latitude == latitude && o.longitude == longitude; - - @override - int get hashCode => hashValues(latitude, longitude); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 7b6167359454..aa0564b0185a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -12,11 +12,11 @@ class DocumentReferenceWeb extends DocumentReference { @override Future setData(Map data, {bool merge = false}) => delegate.set( - FieldValueWeb._serverDelegates(data), web.SetOptions(merge: merge)); + CodecUtility._encodeMapData(data), web.SetOptions(merge: merge)); @override Future updateData(Map data) => - delegate.update(data: FieldValueWeb._serverDelegates(data)); + delegate.update(data: CodecUtility._encodeMapData(data)); @override Future get({Source source = Source.serverAndCache}) async { @@ -34,7 +34,7 @@ class DocumentReferenceWeb extends DocumentReference { DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - webSnapshot.data(), + CodecUtility._decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index c850a7598f13..96b65798c0db 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -1,18 +1,6 @@ part of cloud_firestore_web; class FieldValueWeb implements FieldValueInterface, web.FieldValue { - static Map _serverDelegates(Map data) { - Map output = Map.from(data); - output.updateAll((key, value) { - if (value is FieldValueInterface && value.instance is FieldValueWeb) { - return (value.instance as FieldValueWeb)._delegate; - } else { - return value; - } - }); - return output; - } - web.FieldValue _delegate; FieldValueWeb._(this._delegate, this.type, this.value); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index b1cdb136fd8f..91a5b6cfdeee 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -9,6 +9,8 @@ import 'package:firebase/firestore.dart' as web; part 'collection_reference_web.dart'; +part 'utils/codec_utility.dart'; + part 'field_value_factory_web.dart'; part 'document_reference_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 322da62b85b8..b3af5e16a78a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -28,7 +28,7 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, - FieldValueWeb._serverDelegates(data)); + CodecUtility._encodeMapData(data)); } @override @@ -37,13 +37,13 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, - data: FieldValueWeb._serverDelegates(data)); + data: CodecUtility._encodeMapData(data)); } DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - webSnapshot.data(), + CodecUtility._decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart new file mode 100644 index 000000000000..1d0c3b7ad7f3 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -0,0 +1,33 @@ +part of cloud_firestore_web; + +class CodecUtility { + static Map _encodeMapData(Map data) { + Map output = Map.from(data); + output.updateAll((key, value) { + if (value is FieldValueInterface && value.instance is FieldValueWeb) { + return (value.instance as FieldValueWeb)._delegate; + } else if (value is GeoPoint) { + return web.GeoPoint(value.latitude, value.longitude); + } else if (value is Blob) { + return web.Blob.fromUint8Array(value.bytes); + } else { + return value; + } + }); + return output; + } + + static Map _decodeMapData(Map data) { + Map output = Map.from(data); + output.updateAll((key, value) { + if (value is web.GeoPoint) { + return GeoPoint(value.latitude, value.longitude); + } else if (value is web.Blob) { + return Blob(value.toUint8Array()); + } else { + return value; + } + }); + return output; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 8e886e632564..7a9508285113 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -22,7 +22,7 @@ class WriteBatchWeb implements WriteBatch { assert(document is DocumentReferenceWeb); _delegate.set( (document as DocumentReferenceWeb).delegate, - FieldValueWeb._serverDelegates(data), + CodecUtility._encodeMapData(data), merge ? web.SetOptions(merge: merge) : null); } @@ -30,6 +30,6 @@ class WriteBatchWeb implements WriteBatch { void updateData(DocumentReference document, Map data) { assert(document is DocumentReferenceWeb); _delegate.set((document as DocumentReferenceWeb).delegate, - FieldValueWeb._serverDelegates(data)); + CodecUtility._encodeMapData(data)); } } From e74a2309e50aa49eb350020a9f0a78644b4c8016 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 17:17:02 +0000 Subject: [PATCH 050/144] Started code utility stuff --- .../cloud_firestore/lib/src/document_reference.dart | 8 +++++++- .../cloud_firestore/lib/src/utils/codec_utils.dart | 1 + .../cloud_firestore_web/lib/firestore_web.dart | 1 + .../cloud_firestore_web/lib/utils/codec_utility.dart | 8 ++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 4d7417aa6bf8..a65afdf533ac 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -42,7 +42,13 @@ class DocumentReference { /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. Future setData(Map data, {bool merge = false}) { - return _delegate.setData(data, merge: merge); + return _delegate.setData(data..updateAll((key,value) { + if(value is DocumentReference) { + return value._delegate; + } else { + return value; + } + }), merge: merge); } /// Updates fields in the document referred to by this [DocumentReference]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart new file mode 100644 index 000000000000..a1979617beed --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart @@ -0,0 +1 @@ +//TODO: Add Code utils for handling document references \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 91a5b6cfdeee..416ff3cf2d12 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,6 +4,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 1d0c3b7ad7f3..3a5e9c460f50 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -10,6 +10,8 @@ class CodecUtility { return web.GeoPoint(value.latitude, value.longitude); } else if (value is Blob) { return web.Blob.fromUint8Array(value.bytes); + } else if(value is DocumentReferenceWeb) { + return value.delegate; } else { return value; } @@ -24,6 +26,12 @@ class CodecUtility { return GeoPoint(value.latitude, value.longitude); } else if (value is web.Blob) { return Blob(value.toUint8Array()); + } else if(value is web.DocumentReference) { + return DocumentReferenceWeb( + (FirestorePlatform.instance as FirestoreWeb).webFirestore, + FirestorePlatform.instance, + value.path.split("/") + ); } else { return value; } From 3932bdf2711d172d4c51b2fb58fa1886ad37d076 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 19:49:41 +0000 Subject: [PATCH 051/144] Handle maps and arrays for codec conversions --- .../cloud_firestore/lib/cloud_firestore.dart | 1 + .../lib/src/document_reference.dart | 13 ++- .../lib/src/document_snapshot.dart | 3 +- .../cloud_firestore/lib/src/transaction.dart | 6 +- .../lib/src/utils/codec_utility.dart | 47 +++++++++++ .../lib/src/utils/codec_utils.dart | 1 - .../cloud_firestore/lib/src/write_batch.dart | 7 +- .../lib/document_reference_web.dart | 6 +- .../lib/transaction_web.dart | 6 +- .../lib/utils/codec_utility.dart | 79 ++++++++++++------- .../lib/write_batch_web.dart | 4 +- 11 files changed, 122 insertions(+), 51 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 0216eaa12cb0..d81fe4da1207 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -26,6 +26,7 @@ part 'src/field_value.dart'; part 'src/firestore.dart'; part 'src/query.dart'; part 'src/query_snapshot.dart'; +part 'src/utils/codec_utility.dart'; part 'src/snapshot_metadata.dart'; part 'src/timestamp.dart'; part 'src/transaction.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index a65afdf533ac..5bc59b1444c2 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -42,13 +42,9 @@ class DocumentReference { /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. Future setData(Map data, {bool merge = false}) { - return _delegate.setData(data..updateAll((key,value) { - if(value is DocumentReference) { - return value._delegate; - } else { - return value; - } - }), merge: merge); + return _delegate.setData( + _CodecUtility._replaceValueWithDelegatesInMap(data), + merge: merge); } /// Updates fields in the document referred to by this [DocumentReference]. @@ -58,7 +54,8 @@ class DocumentReference { /// /// If no document exists yet, the update will fail. Future updateData(Map data) { - return _delegate.updateData(data); + return _delegate + .updateData(_CodecUtility._replaceValueWithDelegatesInMap(data)); } /// Reads the document referenced by this [DocumentReference]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 38bd582a666a..1ed047f9383e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -19,7 +19,8 @@ class DocumentSnapshot { _firestore.document(_delegate.reference.path); /// Contains all the data of this snapshot - Map get data => _delegate.data; + Map get data => + _CodecUtility._replaceDelegatesWithValueInMap(_delegate.data); /// Metadata about this snapshot concerning its source and if it has local /// modifications. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 2356ea89b910..0118732ae0c3 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -39,7 +39,8 @@ class Transaction { /// when the transaction handler completes. Future update( DocumentReference documentReference, Map data) async { - return _delegate.update(documentReference._delegate, data); + return _delegate.update(documentReference._delegate, + _CodecUtility._replaceValueWithDelegatesInMap(data)); } /// Writes to the document referred to by the provided [DocumentReference]. @@ -50,6 +51,7 @@ class Transaction { /// when the transaction handler completes. Future set( DocumentReference documentReference, Map data) { - return _delegate.set(documentReference._delegate, data); + return _delegate.set(documentReference._delegate, + _CodecUtility._replaceValueWithDelegatesInMap(data)); } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart new file mode 100644 index 000000000000..ed3e89b91fb0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -0,0 +1,47 @@ +part of cloud_firestore; + +class _CodecUtility { + static Map _replaceValueWithDelegatesInMap( + Map data) { + Map output = Map.from(data); + output.updateAll((_, value) => _valueEncode(value)); + return output; + } + + static List _replaceValueWithDelegatesInArray(List data) { + return List.from(data).map((value) => _valueEncode(value)); + } + + static Map _replaceDelegatesWithValueInMap( + Map data) { + Map output = Map.from(data); + output.updateAll((_, value) => _valueDecode(value)); + return output; + } + + static List _replaceDelegatesWithValueInArray(List data) { + return List.from(data).map((value) => _valueDecode(value)); + } + + static dynamic _valueEncode(dynamic value) { + if (value is DocumentReference) { + return value._delegate; + } else if (value is List) { + _replaceValueWithDelegatesInArray(value); + } else if (value is Map) { + _replaceValueWithDelegatesInMap(value); + } + return value; + } + + static dynamic _valueDecode(dynamic value) { + if (value is platform.DocumentReference) { + return DocumentReference._(value); + } else if (value is List) { + _replaceDelegatesWithValueInArray(value); + } else if (value is Map) { + _replaceDelegatesWithValueInMap(value); + } + return value; + } +} diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart deleted file mode 100644 index a1979617beed..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utils.dart +++ /dev/null @@ -1 +0,0 @@ -//TODO: Add Code utils for handling document references \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index a9fcb32d575e..05752d8d77fc 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -22,8 +22,11 @@ class WriteBatch { void setData(DocumentReference document, Map data, {bool merge = false}) => - _delegate.setData(document._delegate, data, merge: merge); + _delegate.setData(document._delegate, + _CodecUtility._replaceValueWithDelegatesInMap(data), + merge: merge); void updateData(DocumentReference document, Map data) => - _delegate.updateData(document._delegate, data); + _delegate.updateData(document._delegate, + _CodecUtility._replaceValueWithDelegatesInMap(data)); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index aa0564b0185a..23c310c97e99 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -12,11 +12,11 @@ class DocumentReferenceWeb extends DocumentReference { @override Future setData(Map data, {bool merge = false}) => delegate.set( - CodecUtility._encodeMapData(data), web.SetOptions(merge: merge)); + _CodecUtility._encodeMapData(data), web.SetOptions(merge: merge)); @override Future updateData(Map data) => - delegate.update(data: CodecUtility._encodeMapData(data)); + delegate.update(data: _CodecUtility._encodeMapData(data)); @override Future get({Source source = Source.serverAndCache}) async { @@ -34,7 +34,7 @@ class DocumentReferenceWeb extends DocumentReference { DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - CodecUtility._decodeMapData(webSnapshot.data()), + _CodecUtility._decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index b3af5e16a78a..f421cee25e36 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -28,7 +28,7 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, - CodecUtility._encodeMapData(data)); + _CodecUtility._encodeMapData(data)); } @override @@ -37,13 +37,13 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, - data: CodecUtility._encodeMapData(data)); + data: _CodecUtility._encodeMapData(data)); } DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - CodecUtility._decodeMapData(webSnapshot.data()), + _CodecUtility._decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 3a5e9c460f50..3921717bb8e8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -1,41 +1,62 @@ part of cloud_firestore_web; -class CodecUtility { +class _CodecUtility { static Map _encodeMapData(Map data) { Map output = Map.from(data); - output.updateAll((key, value) { - if (value is FieldValueInterface && value.instance is FieldValueWeb) { - return (value.instance as FieldValueWeb)._delegate; - } else if (value is GeoPoint) { - return web.GeoPoint(value.latitude, value.longitude); - } else if (value is Blob) { - return web.Blob.fromUint8Array(value.bytes); - } else if(value is DocumentReferenceWeb) { - return value.delegate; - } else { - return value; - } - }); + output.updateAll((key, value) => _valueEncode(value)); return output; } + static List _encodeArrayData(List data) { + List output = List.from(data); + output.map(_valueEncode); + return output; + } + + static dynamic _valueEncode(dynamic value) { + if (value is FieldValueInterface && value.instance is FieldValueWeb) { + return (value.instance as FieldValueWeb)._delegate; + } else if (value is GeoPoint) { + return web.GeoPoint(value.latitude, value.longitude); + } else if (value is Blob) { + return web.Blob.fromUint8Array(value.bytes); + } else if (value is DocumentReferenceWeb) { + return value.delegate; + } else if (value is Map) { + return _encodeMapData(value); + } else if (value is List) { + return _encodeArrayData(value); + } + return value; + } + static Map _decodeMapData(Map data) { Map output = Map.from(data); - output.updateAll((key, value) { - if (value is web.GeoPoint) { - return GeoPoint(value.latitude, value.longitude); - } else if (value is web.Blob) { - return Blob(value.toUint8Array()); - } else if(value is web.DocumentReference) { - return DocumentReferenceWeb( - (FirestorePlatform.instance as FirestoreWeb).webFirestore, - FirestorePlatform.instance, - value.path.split("/") - ); - } else { - return value; - } - }); + output.updateAll((key, value) => _valueDecode(value)); return output; } + + static List _decodeArrayData(List data) { + List output = List.from(data); + output.map(_valueDecode); + return output; + } + + static dynamic _valueDecode(dynamic value) { + if (value is web.GeoPoint) { + return GeoPoint(value.latitude, value.longitude); + } else if (value is web.Blob) { + return Blob(value.toUint8Array()); + } else if (value is web.DocumentReference) { + return DocumentReferenceWeb( + (FirestorePlatform.instance as FirestoreWeb).webFirestore, + FirestorePlatform.instance, + value.path.split("/")); + } else if (value is Map) { + return _decodeMapData(value); + } else if (value is List) { + return _decodeArrayData(value); + } + return value; + } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 7a9508285113..024c848dcb84 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -22,7 +22,7 @@ class WriteBatchWeb implements WriteBatch { assert(document is DocumentReferenceWeb); _delegate.set( (document as DocumentReferenceWeb).delegate, - CodecUtility._encodeMapData(data), + _CodecUtility._encodeMapData(data), merge ? web.SetOptions(merge: merge) : null); } @@ -30,6 +30,6 @@ class WriteBatchWeb implements WriteBatch { void updateData(DocumentReference document, Map data) { assert(document is DocumentReferenceWeb); _delegate.set((document as DocumentReferenceWeb).delegate, - CodecUtility._encodeMapData(data)); + _CodecUtility._encodeMapData(data)); } } From 67574b19d2a7c2222d2b173380c1cfde4548f099 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 19:55:19 +0000 Subject: [PATCH 052/144] Removed cupertino import --- .../cloud_firestore/cloud_firestore_web/lib/firestore_web.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 416ff3cf2d12..91a5b6cfdeee 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,7 +4,6 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; From 7cd3c13a065b272e1d6726d97bd357ab284102db Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 20:38:05 +0000 Subject: [PATCH 053/144] Lazily load Firestore instances --- .../cloud_firestore/lib/src/firestore.dart | 10 ++++++++-- .../lib/cloud_firestore_platform_interface.dart | 9 +++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index a179071f1ddb..e02ef3e64f14 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -8,10 +8,16 @@ part of cloud_firestore; /// /// You can get an instance by calling [Firestore.instance]. class Firestore { - final platform.FirestorePlatform _delegate; + platform.FirestorePlatform _delegatePackingProperty; + platform.FirestorePlatform get _delegate { + if (_delegatePackingProperty == null) { + _delegatePackingProperty = platform.FirestorePlatform.instance; + } + return _delegatePackingProperty; + } Firestore({FirebaseApp app, platform.FirestorePlatform delegate}) - : _delegate = delegate ?? platform.FirestorePlatform.instance; + : _delegatePackingProperty = delegate; static MethodChannel get channel => platform.MethodChannelFirestore.channel; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 0e5b9a81cbba..c69a8c0655c6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -58,9 +58,14 @@ abstract class FirestorePlatform { @visibleForTesting bool get isMock => false; - static FirestorePlatform get instance => _instance; + static FirestorePlatform get instance { + if (_instance == null) { + _instance = MethodChannelFirestore(); + } + return _instance; + } - static FirestorePlatform _instance = MethodChannelFirestore(); + static FirestorePlatform _instance; static set instance(FirestorePlatform instance) { if (!instance.isMock) { From 64392c49ff0a8585d3c0ccac203eeb622484ff9f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 19 Dec 2019 21:40:03 +0000 Subject: [PATCH 054/144] PR Feedback fixes --- .../lib/src/document_reference.dart | 5 +- .../lib/src/document_snapshot.dart | 2 +- .../cloud_firestore/lib/src/firestore.dart | 2 +- .../cloud_firestore/lib/src/transaction.dart | 6 +- .../lib/src/utils/codec_utility.dart | 28 ++--- .../cloud_firestore/lib/src/write_batch.dart | 4 +- .../cloud_firestore/pubspec.yaml | 1 - .../lib/src/write_batch.dart | 116 +++++++++--------- .../lib/document_reference_web.dart | 6 +- .../cloud_firestore_web/lib/query_web.dart | 13 +- .../lib/transaction_web.dart | 6 +- .../lib/utils/codec_utility.dart | 28 ++--- .../lib/write_batch_web.dart | 4 +- 13 files changed, 108 insertions(+), 113 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 5bc59b1444c2..c807f7663b5c 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -42,8 +42,7 @@ class DocumentReference { /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. Future setData(Map data, {bool merge = false}) { - return _delegate.setData( - _CodecUtility._replaceValueWithDelegatesInMap(data), + return _delegate.setData(_CodecUtility.replaceValueWithDelegatesInMap(data), merge: merge); } @@ -55,7 +54,7 @@ class DocumentReference { /// If no document exists yet, the update will fail. Future updateData(Map data) { return _delegate - .updateData(_CodecUtility._replaceValueWithDelegatesInMap(data)); + .updateData(_CodecUtility.replaceValueWithDelegatesInMap(data)); } /// Reads the document referenced by this [DocumentReference]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 1ed047f9383e..6d2df1b49f60 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -20,7 +20,7 @@ class DocumentSnapshot { /// Contains all the data of this snapshot Map get data => - _CodecUtility._replaceDelegatesWithValueInMap(_delegate.data); + _CodecUtility.replaceDelegatesWithValueInMap(_delegate.data); /// Metadata about this snapshot concerning its source and if it has local /// modifications. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index e02ef3e64f14..5c874540b44a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -53,7 +53,7 @@ class Firestore { DocumentReference document(String path) => DocumentReference._(_delegate.document(path)); - @deprecated + @Deprecated('Use the persistenceEnabled parameter of the [settings] method') Future enablePersistence(bool enable) => _delegate.enablePersistence(enable); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 0118732ae0c3..70b308ed60ae 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -4,6 +4,8 @@ part of cloud_firestore; +/// The TransactionHandler may be executed multiple times, it should be able +/// to handle multiple executions. typedef Future TransactionHandler(Transaction transaction); class Transaction { @@ -40,7 +42,7 @@ class Transaction { Future update( DocumentReference documentReference, Map data) async { return _delegate.update(documentReference._delegate, - _CodecUtility._replaceValueWithDelegatesInMap(data)); + _CodecUtility.replaceValueWithDelegatesInMap(data)); } /// Writes to the document referred to by the provided [DocumentReference]. @@ -52,6 +54,6 @@ class Transaction { Future set( DocumentReference documentReference, Map data) { return _delegate.set(documentReference._delegate, - _CodecUtility._replaceValueWithDelegatesInMap(data)); + _CodecUtility.replaceValueWithDelegatesInMap(data)); } } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index ed3e89b91fb0..e53bdcb017f2 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -1,46 +1,46 @@ part of cloud_firestore; class _CodecUtility { - static Map _replaceValueWithDelegatesInMap( + static Map replaceValueWithDelegatesInMap( Map data) { Map output = Map.from(data); - output.updateAll((_, value) => _valueEncode(value)); + output.updateAll((_, value) => valueEncode(value)); return output; } - static List _replaceValueWithDelegatesInArray(List data) { - return List.from(data).map((value) => _valueEncode(value)); + static List replaceValueWithDelegatesInArray(List data) { + return List.from(data).map((value) => valueEncode(value)); } - static Map _replaceDelegatesWithValueInMap( + static Map replaceDelegatesWithValueInMap( Map data) { Map output = Map.from(data); - output.updateAll((_, value) => _valueDecode(value)); + output.updateAll((_, value) => valueDecode(value)); return output; } - static List _replaceDelegatesWithValueInArray(List data) { - return List.from(data).map((value) => _valueDecode(value)); + static List replaceDelegatesWithValueInArray(List data) { + return List.from(data).map((value) => valueDecode(value)); } - static dynamic _valueEncode(dynamic value) { + static dynamic valueEncode(dynamic value) { if (value is DocumentReference) { return value._delegate; } else if (value is List) { - _replaceValueWithDelegatesInArray(value); + return replaceValueWithDelegatesInArray(value); } else if (value is Map) { - _replaceValueWithDelegatesInMap(value); + return replaceValueWithDelegatesInMap(value); } return value; } - static dynamic _valueDecode(dynamic value) { + static dynamic valueDecode(dynamic value) { if (value is platform.DocumentReference) { return DocumentReference._(value); } else if (value is List) { - _replaceDelegatesWithValueInArray(value); + return replaceDelegatesWithValueInArray(value); } else if (value is Map) { - _replaceDelegatesWithValueInMap(value); + return replaceDelegatesWithValueInMap(value); } return value; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 05752d8d77fc..9a568fa024fa 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -23,10 +23,10 @@ class WriteBatch { void setData(DocumentReference document, Map data, {bool merge = false}) => _delegate.setData(document._delegate, - _CodecUtility._replaceValueWithDelegatesInMap(data), + _CodecUtility.replaceValueWithDelegatesInMap(data), merge: merge); void updateData(DocumentReference document, Map data) => _delegate.updateData(document._delegate, - _CodecUtility._replaceValueWithDelegatesInMap(data)); + _CodecUtility.replaceValueWithDelegatesInMap(data)); } diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index d7565e12b12b..ae90f494929d 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -20,7 +20,6 @@ dependencies: flutter: sdk: flutter meta: "^1.0.5" - collection: "^1.14.3" firebase_core: "^0.4.0" cloud_firestore_platform_interface: path: ../cloud_firestore_platform_interface diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart index 9b4ec5415867..d20a3897dc09 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart @@ -23,80 +23,76 @@ class WriteBatch extends WriteBatchPlatform { @override Future commit() async { - if (!_committed) { - _committed = true; - await Future.wait(_actions); - await MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#commit', {'handle': await _handle}); - } else { - throw StateError("This batch has already been committed."); - } + _assertNotCommitted(); + + _committed = true; + await Future.wait(_actions); + await MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#commit', {'handle': await _handle}); } @override void delete(DocumentReference document) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#delete', - { - 'app': _firestore.appName(), - 'handle': handle, - 'path': document.path, - }, - ), - ); - }); - } else { - throw StateError( - "This batch has been committed and can no longer be changed."); - } + _assertNotCommitted(); + + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#delete', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + }, + ), + ); + }); } @override void setData(DocumentReference document, Map data, {bool merge = false}) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#setData', - { - 'app': _firestore.appName(), - 'handle': handle, - 'path': document.path, - 'data': data, - 'options': {'merge': merge}, - }, - ), - ); - }); - } else { - throw StateError( - "This batch has been committed and can no longer be changed."); - } + _assertNotCommitted(); + + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#setData', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + 'data': data, + 'options': {'merge': merge}, + }, + ), + ); + }); } @override void updateData(DocumentReference document, Map data) { - if (!_committed) { - _handle.then((dynamic handle) { - _actions.add( - MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#updateData', - { - 'app': _firestore.appName(), - 'handle': handle, - 'path': document.path, - 'data': data, - }, - ), - ); - }); - } else { + _assertNotCommitted(); + + _handle.then((dynamic handle) { + _actions.add( + MethodChannelFirestore.channel.invokeMethod( + 'WriteBatch#updateData', + { + 'app': _firestore.appName(), + 'handle': handle, + 'path': document.path, + 'data': data, + }, + ), + ); + }); + } + + void _assertNotCommitted() { + if (_committed) { throw StateError( - "This batch has been committed and can no longer be changed."); + 'This batch has already been committed and can no longer be changed.'); } } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 23c310c97e99..bed910fcf077 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -12,11 +12,11 @@ class DocumentReferenceWeb extends DocumentReference { @override Future setData(Map data, {bool merge = false}) => delegate.set( - _CodecUtility._encodeMapData(data), web.SetOptions(merge: merge)); + _CodecUtility.encodeMapData(data), web.SetOptions(merge: merge)); @override Future updateData(Map data) => - delegate.update(data: _CodecUtility._encodeMapData(data)); + delegate.update(data: _CodecUtility.encodeMapData(data)); @override Future get({Source source = Source.serverAndCache}) async { @@ -34,7 +34,7 @@ class DocumentReferenceWeb extends DocumentReference { DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - _CodecUtility._decodeMapData(webSnapshot.data()), + _CodecUtility.decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 411d4267f92f..5d8b1418292b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -6,9 +6,9 @@ class QueryWeb implements Query { final bool _isCollectionGroup; final String _path; final List _orderByKeys; - static const _changeTypeAdded = "added"; - static const _changeTypeModified = "modified"; - static const _changeTypeRemoved = "removed"; + static const _kChangeTypeAdded = "added"; + static const _kChangeTypeModified = "modified"; + static const _kChangeTypeRemoved = "removed"; QueryWeb(this._firestore, this._path, this.webQuery, {bool isCollectionGroup, List orderByKeys}) @@ -159,7 +159,6 @@ class QueryWeb implements Query { 'Supported [field] types are [String] and [FieldPath].'); assert(webQuery != null); dynamic usableField = field; - ; if (field == FieldPath.documentId) { usableField = web.FieldPath.documentId(); } @@ -222,11 +221,11 @@ class QueryWeb implements Query { DocumentChangeType _fromString(String item) { switch (item.toLowerCase()) { - case _changeTypeAdded: + case _kChangeTypeAdded: return DocumentChangeType.added; - case _changeTypeModified: + case _kChangeTypeModified: return DocumentChangeType.modified; - case _changeTypeRemoved: + case _kChangeTypeRemoved: return DocumentChangeType.removed; default: throw ArgumentError("Invalid type"); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index f421cee25e36..8f58d0885c43 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -28,7 +28,7 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, - _CodecUtility._encodeMapData(data)); + _CodecUtility.encodeMapData(data)); } @override @@ -37,13 +37,13 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, - data: _CodecUtility._encodeMapData(data)); + data: _CodecUtility.encodeMapData(data)); } DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - _CodecUtility._decodeMapData(webSnapshot.data()), + _CodecUtility.decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 3921717bb8e8..5fd76065ae1b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -1,19 +1,19 @@ part of cloud_firestore_web; class _CodecUtility { - static Map _encodeMapData(Map data) { + static Map encodeMapData(Map data) { Map output = Map.from(data); - output.updateAll((key, value) => _valueEncode(value)); + output.updateAll((key, value) => valueEncode(value)); return output; } - static List _encodeArrayData(List data) { + static List encodeArrayData(List data) { List output = List.from(data); - output.map(_valueEncode); + output.map(valueEncode); return output; } - static dynamic _valueEncode(dynamic value) { + static dynamic valueEncode(dynamic value) { if (value is FieldValueInterface && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb)._delegate; } else if (value is GeoPoint) { @@ -23,26 +23,26 @@ class _CodecUtility { } else if (value is DocumentReferenceWeb) { return value.delegate; } else if (value is Map) { - return _encodeMapData(value); + return encodeMapData(value); } else if (value is List) { - return _encodeArrayData(value); + return encodeArrayData(value); } return value; } - static Map _decodeMapData(Map data) { + static Map decodeMapData(Map data) { Map output = Map.from(data); - output.updateAll((key, value) => _valueDecode(value)); + output.updateAll((key, value) => valueDecode(value)); return output; } - static List _decodeArrayData(List data) { + static List decodeArrayData(List data) { List output = List.from(data); - output.map(_valueDecode); + output.map(valueDecode); return output; } - static dynamic _valueDecode(dynamic value) { + static dynamic valueDecode(dynamic value) { if (value is web.GeoPoint) { return GeoPoint(value.latitude, value.longitude); } else if (value is web.Blob) { @@ -53,9 +53,9 @@ class _CodecUtility { FirestorePlatform.instance, value.path.split("/")); } else if (value is Map) { - return _decodeMapData(value); + return decodeMapData(value); } else if (value is List) { - return _decodeArrayData(value); + return decodeArrayData(value); } return value; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 024c848dcb84..f73eae267582 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -22,7 +22,7 @@ class WriteBatchWeb implements WriteBatch { assert(document is DocumentReferenceWeb); _delegate.set( (document as DocumentReferenceWeb).delegate, - _CodecUtility._encodeMapData(data), + _CodecUtility.encodeMapData(data), merge ? web.SetOptions(merge: merge) : null); } @@ -30,6 +30,6 @@ class WriteBatchWeb implements WriteBatch { void updateData(DocumentReference document, Map data) { assert(document is DocumentReferenceWeb); _delegate.set((document as DocumentReferenceWeb).delegate, - _CodecUtility._encodeMapData(data)); + _CodecUtility.encodeMapData(data)); } } From 99670673ee83bcc47e4e6bc80aeefe3dc0af95bd Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:13:51 +0000 Subject: [PATCH 055/144] Use PlatformInterface to check for verify implementation --- .../cloud_firestore_platform_interface.dart | 33 ++++--------------- .../pubspec.yaml | 1 + 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index c69a8c0655c6..b46b6039ea71 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -11,6 +11,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; part 'src/method_channel_firestore.dart'; part 'src/blob.dart'; @@ -40,24 +41,18 @@ part 'src/transaction_platform_interface.dart'; part 'src/write_batch.dart'; part 'src/write_batch_platform_interface.dart'; -abstract class FirestorePlatform { +abstract class FirestorePlatform extends PlatformInterface { final FirebaseApp app; - FirestorePlatform({FirebaseApp app}) : app = app ?? FirebaseApp.instance; + FirestorePlatform({FirebaseApp app}) : app = app ?? FirebaseApp.instance, super(token: _token); + + static final Object _token = Object(); factory FirestorePlatform.withApp({FirebaseApp app}) { FirestorePlatform.instance = FirestorePlatform.instance.withApp(app); return FirestorePlatform.instance; } - /// Only mock implementations should set this to `true`. - /// - /// Mockito mocks implement this class with `implements` which is forbidden - /// (see class docs). This property provides a backdoor for mocks to skip the - /// verification that the class isn't implemented with `implements`. - @visibleForTesting - bool get isMock => false; - static FirestorePlatform get instance { if (_instance == null) { _instance = MethodChannelFirestore(); @@ -68,14 +63,7 @@ abstract class FirestorePlatform { static FirestorePlatform _instance; static set instance(FirestorePlatform instance) { - if (!instance.isMock) { - try { - instance._verifyProvidesDefaultImplementations(); - } on NoSuchMethodError catch (_) { - throw AssertionError( - 'Platform interfaces must not be implemented with `implements`'); - } - } + PlatformInterface.verifyToken(instance, _token); _instance = instance; } @@ -87,15 +75,6 @@ abstract class FirestorePlatform { throw UnimplementedError("appName() not implemented"); } - /// This method ensures that [FirestorePlatform] isn't implemented with `implements`. - /// - /// See class docs for more details on why using `implements` to implement - /// [FirestorePlatform] is forbidden. - /// - /// This private method is called by the [instance] setter, which should fail - /// if the provided instance is a class implemented with `implements`. - void _verifyProvidesDefaultImplementations() {} - /// Gets a [CollectionReference] for the specified Firestore path. CollectionReference collection(String path) { throw UnimplementedError('collection() is not implemented'); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml index 0761e0d83c86..73daeb791427 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/pubspec.yaml @@ -9,6 +9,7 @@ dependencies: meta: ^1.0.5 collection: ^1.14.3 firebase_core: ^0.4.3+1 + plugin_platform_interface: ^1.0.0 dev_dependencies: flutter_test: From 164b8b57b8109c043e61fd7a2969ef707f433967 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:16:40 +0000 Subject: [PATCH 056/144] removed comments on analysis file --- .../cloud_firestore_web/analysis_options.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml index bbfa25e2146a..880f38c52a83 100644 --- a/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml @@ -1,8 +1,3 @@ -# This is a temporary file to allow us to land a new set of linter rules in a -# series of manageable patches instead of one gigantic PR. It disables some of -# the new lints that are already failing on this plugin, for this plugin. It -# should be deleted and the failing lints addressed as soon as possible. - include: ../../../analysis_options.yaml analyzer: From b6050f91b32aaf4819098b36f661760f8a90095c Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:20:07 +0000 Subject: [PATCH 057/144] removed todo as its not a client side logic --- .../cloud_firestore_web/lib/document_reference_web.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index bed910fcf077..54004700a485 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -20,7 +20,6 @@ class DocumentReferenceWeb extends DocumentReference { @override Future get({Source source = Source.serverAndCache}) async { - //TODO(amr): Honour source by passing it to the delegate return _fromWeb(await delegate.get()); } From 762daae3bdf6096c1984a558e8db041bdb4804c6 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:28:14 +0000 Subject: [PATCH 058/144] Removed ensureInitialized() call --- .../cloud_firestore/example/lib/main.dart | 31 ++++++++++--------- .../cloud_firestore_platform_interface.dart | 4 ++- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart index 34bffa9cb9f2..d928b2308002 100755 --- a/packages/cloud_firestore/cloud_firestore/example/lib/main.dart +++ b/packages/cloud_firestore/cloud_firestore/example/lib/main.dart @@ -9,20 +9,23 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; Future main() async { - WidgetsFlutterBinding.ensureInitialized(); - final FirebaseApp app = await FirebaseApp.configure( - name: 'test', - options: const FirebaseOptions( - googleAppID: '1:79601577497:ios:5f2bcc6ba8cecddd', - gcmSenderID: '79601577497', - apiKey: 'AIzaSyArgmRGfB5kiQT6CunAOmKRVKEsxKmy6YI-G72PVU', - projectID: 'flutter-firestore', - ), - ); - final Firestore firestore = Firestore(app: app); - - runApp(MaterialApp( - title: 'Firestore Example', home: MyHomePage(firestore: firestore))); + runApp(MaterialApp(title: 'Firestore Example', home: AppConfig())); +} + +class AppConfig extends StatelessWidget { + @override + Widget build(BuildContext context) => FutureBuilder( + future: FirebaseApp.configure( + name: 'test', + options: const FirebaseOptions( + googleAppID: '1:79601577497:ios:5f2bcc6ba8cecddd', + gcmSenderID: '79601577497', + apiKey: 'AIzaSyArgmRGfB5kiQT6CunAOmKRVKEsxKmy6YI-G72PVU', + projectID: 'flutter-firestore', + ), + ), + builder: (BuildContext context, AsyncSnapshot snapshot) => + MyHomePage(firestore: Firestore(app: snapshot.data))); } class MessageList extends StatelessWidget { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index b46b6039ea71..332ad284ef68 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -44,7 +44,9 @@ part 'src/write_batch_platform_interface.dart'; abstract class FirestorePlatform extends PlatformInterface { final FirebaseApp app; - FirestorePlatform({FirebaseApp app}) : app = app ?? FirebaseApp.instance, super(token: _token); + FirestorePlatform({FirebaseApp app}) + : app = app ?? FirebaseApp.instance, + super(token: _token); static final Object _token = Object(); From 20823037fe09d5735acd73f6028da732cb61a5d2 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:36:14 +0000 Subject: [PATCH 059/144] Added null checks for codec_utility --- .../cloud_firestore/lib/src/utils/codec_utility.dart | 12 ++++++++++++ .../cloud_firestore_web/lib/utils/codec_utility.dart | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index e53bdcb017f2..d5d967b43c28 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -3,23 +3,35 @@ part of cloud_firestore; class _CodecUtility { static Map replaceValueWithDelegatesInMap( Map data) { + if (data == null) { + return null; + } Map output = Map.from(data); output.updateAll((_, value) => valueEncode(value)); return output; } static List replaceValueWithDelegatesInArray(List data) { + if (data == null) { + return null; + } return List.from(data).map((value) => valueEncode(value)); } static Map replaceDelegatesWithValueInMap( Map data) { + if (data == null) { + return null; + } Map output = Map.from(data); output.updateAll((_, value) => valueDecode(value)); return output; } static List replaceDelegatesWithValueInArray(List data) { + if (data == null) { + return null; + } return List.from(data).map((value) => valueDecode(value)); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 5fd76065ae1b..744135630bd5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -2,12 +2,18 @@ part of cloud_firestore_web; class _CodecUtility { static Map encodeMapData(Map data) { + if (data == null) { + return null; + } Map output = Map.from(data); output.updateAll((key, value) => valueEncode(value)); return output; } static List encodeArrayData(List data) { + if (data == null) { + return null; + } List output = List.from(data); output.map(valueEncode); return output; From d3c65ad34b631c92c319d241ab88c6f6c23e57cf Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:36:52 +0000 Subject: [PATCH 060/144] Use setUpAll for test --- .../cloud_firestore/example/test_driver/cloud_firestore.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore/example/test_driver/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/example/test_driver/cloud_firestore.dart index c154f80f6271..3cf96d55d199 100644 --- a/packages/cloud_firestore/cloud_firestore/example/test_driver/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/example/test_driver/cloud_firestore.dart @@ -14,7 +14,7 @@ void main() { Firestore firestore; Firestore firestoreWithSettings; - setUp(() async { + setUpAll(() async { final FirebaseOptions firebaseOptions = const FirebaseOptions( googleAppID: '1:79601577497:ios:5f2bcc6ba8cecddd', gcmSenderID: '79601577497', From a2623e188556a774be823a3d0abf76db4b787270 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 10:55:31 +0000 Subject: [PATCH 061/144] Use toList() --- .../cloud_firestore/lib/src/utils/codec_utility.dart | 4 ++-- .../cloud_firestore_web/lib/utils/codec_utility.dart | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index d5d967b43c28..bfa7b2a4788c 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -15,7 +15,7 @@ class _CodecUtility { if (data == null) { return null; } - return List.from(data).map((value) => valueEncode(value)); + return List.from(data).map((value) => valueEncode(value)).toList(); } static Map replaceDelegatesWithValueInMap( @@ -32,7 +32,7 @@ class _CodecUtility { if (data == null) { return null; } - return List.from(data).map((value) => valueDecode(value)); + return List.from(data).map((value) => valueDecode(value)).toList(); } static dynamic valueEncode(dynamic value) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 744135630bd5..3b5831778da5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -14,9 +14,7 @@ class _CodecUtility { if (data == null) { return null; } - List output = List.from(data); - output.map(valueEncode); - return output; + return List.from(data).map(valueEncode).toList(); } static dynamic valueEncode(dynamic value) { @@ -43,9 +41,7 @@ class _CodecUtility { } static List decodeArrayData(List data) { - List output = List.from(data); - output.map(valueDecode); - return output; + return List.from(data).map(valueDecode).toList(); } static dynamic valueDecode(dynamic value) { From 73627b6a2f15fd3ded5f6e0cc9e906a68392a135 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 11:07:45 +0000 Subject: [PATCH 062/144] Added platform_interface/document_reference_test.dart --- .../test/document_reference_test.dart | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart new file mode 100644 index 000000000000..89a56bbbe973 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart @@ -0,0 +1,35 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +const _kCollectionId = "test"; +const _kDocumentId = "document"; +class TestDocumentReference extends DocumentReference { + TestDocumentReference._(): super(FirestorePlatform.instance, [_kCollectionId,_kDocumentId]); +} +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group("$DocumentReference()", (){ + test("Parent",(){ + final document = TestDocumentReference._(); + final parent = document.parent(); + final parentPath = parent.path; + expect(parent, isInstanceOf()); + expect(parentPath, equals(_kCollectionId)); + }); + + test("documentID",(){ + final document = TestDocumentReference._(); + expect(document.documentID, equals(_kDocumentId)); + }); + + test("Path",(){ + final document = TestDocumentReference._(); + expect(document.path, equals("$_kCollectionId/$_kDocumentId")); + }); + + test("Collection",(){ + final document = TestDocumentReference._(); + expect(document.collection("extra").path, equals("$_kCollectionId/$_kDocumentId/extra")); + }); + }); +} \ No newline at end of file From f77739db2ed71d0c3edd0667e0b2c303113207f6 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 11:15:19 +0000 Subject: [PATCH 063/144] Added platform_interface field value test --- .../src/platform_interface/field_value.dart | 6 +++++- .../test/field_value_test.dart | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 1a8443d3d3b7..2f19f1fefb86 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -21,7 +21,11 @@ abstract class FieldValueInterface { class FieldValue implements FieldValueInterface { /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValue] - static Map _serverDelegates(Map data) { + @visibleForTesting + static Map serverDelegates(Map data) { + if(data == null) { + return null; + } Map output = Map.from(data); output.updateAll((key, value) { if (value is FieldValueInterface && value.instance is FieldValue) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart new file mode 100644 index 000000000000..4d1b8099c13f --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -0,0 +1,18 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +class MockFieldValue extends Mock implements FieldValueInterface {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group("$FieldValue()", () { + test("ServeDelegates", () { + expect(FieldValue.serverDelegates(null), isNull); + + final mockFieldValue = MockFieldValue(); + FieldValue.serverDelegates({"item": mockFieldValue}); + verify(mockFieldValue.instance); + }); + }); +} From ef5d223487b0723908f7d7ab316e5a2b4c8a6da7 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 11:15:53 +0000 Subject: [PATCH 064/144] Fixed method_channel_document_reference --- .../lib/src/method_channel_document_reference.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart index 1fe28155b242..db7ff4150aa6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart @@ -17,7 +17,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': FieldValue._serverDelegates(data), + 'data': FieldValue.serverDelegates(data), 'options': {'merge': merge}, }, ); @@ -30,7 +30,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': FieldValue._serverDelegates(data), + 'data': FieldValue.serverDelegates(data), }, ); } From 3e7029615a0b5abdaae1780ed49ee1c95f78b909 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 11:18:02 +0000 Subject: [PATCH 065/144] Add comments on public functions for field_value_factory --- .../lib/src/platform_interface/field_value_factory.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 50f32d5d4d97..c2c954cbba3e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -11,11 +11,17 @@ enum FieldValueType { incrementInteger, } +/// An interface for a factory that is used to build [FieldValue] according to +/// Platform (web or mobile) abstract class FieldValueFactory { + + /// Current instance of [FieldValueFactory] static FieldValueFactory get instance => _instance; static FieldValueFactory _instance = MethodChannelFieldValueFactory(); + /// Sets the default instance of [FieldValueFactory] which is used to build + /// [FieldValue] items static set instance(FieldValueFactory instance) { _instance = instance; } From 103f534df0a6820526b21968277b09e187df250e Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 11:31:32 +0000 Subject: [PATCH 066/144] added platform_interface_query_test --- .../test/query_test.dart | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart new file mode 100644 index 000000000000..798a1dfd00d0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart @@ -0,0 +1,38 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +const _kQueryPath = "test/collection"; + +class TestQuery extends MethodChannelQuery { + TestQuery._() + : super( + firestore: FirestorePlatform.instance, + pathComponents: _kQueryPath.split("/")); +} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group("$Query()", () { + test("parameters", () { + _hasDefaultParameters(TestQuery._().parameters); + }); + + test("reference", () { + final testQuery = TestQuery._(); + final actualCollection = testQuery.reference(); + expect(actualCollection, isInstanceOf()); + expect(actualCollection.path, equals(_kQueryPath)); + }); + + test("limit", () { + final testQuery = TestQuery._().limit(1); + expect(testQuery.parameters["limit"], equals(1)); + _hasDefaultParameters(testQuery.parameters); + }); + }); +} + +void _hasDefaultParameters(Map input) { + expect(input["where"], equals([])); + expect(input["orderBy"], equals([])); +} From 85131620831395cf726ad2d5608c5504725e94d3 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 12:57:45 +0000 Subject: [PATCH 067/144] Added unit tests for method channel document and collection reference --- .../lib/src/blob.dart | 2 + .../lib/src/geo_point.dart | 1 + ...hod_channel_collection_reference_test.dart | 45 +++++++ .../method_channel_document_reference.dart | 122 ++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index 1f9e2efe8014..26c09fe19356 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -1,8 +1,10 @@ part of cloud_firestore_platform_interface; +/// Represents binary data stored in [Uint8List] class Blob { const Blob(this.bytes); + /// Blob Data bytes final Uint8List bytes; @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart index d325d72e0a78..7f7b13ab9e46 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -4,6 +4,7 @@ part of cloud_firestore_platform_interface; +/// Represents a geographical point by its longitude and latitude class GeoPoint { const GeoPoint(this.latitude, this.longitude); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart new file mode 100644 index 000000000000..4eabb5a3c4c7 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart @@ -0,0 +1,45 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +const _kCollectionId = "test"; +const _kDocumentId = "document"; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group("$MethodChannelCollectionReference", () { + MethodChannelCollectionReference _testCollection; + setUp(() { + _testCollection = MethodChannelCollectionReference( + FirestorePlatform.instance, [_kCollectionId]); + }); + test("Parent", () { + expect(_testCollection.parent(), isNull); + expect( + MethodChannelCollectionReference(FirestorePlatform.instance, + [_kCollectionId, _kDocumentId, "test"]).parent().path, + equals("$_kCollectionId/$_kDocumentId")); + }); + test("Document", () { + expect(_testCollection.document().path.split("/").length, equals(2)); + expect(_testCollection.document(_kDocumentId).path.split("/").last, + equals(_kDocumentId)); + }); + test("Add",() async { + bool _methodChannelCalled = false; + MethodChannelFirestore.channel.setMockMethodCallHandler((MethodCall methodCall) async { + switch(methodCall.method) { + case "DocumentReference#setData": + expect(methodCall.arguments["data"]["test"], equals("test")); + _methodChannelCalled = true; + break; + default: + return; + } + }); + await _testCollection.add({"test":"test"}); + expect(_methodChannelCalled,isTrue, reason: "DocumentReference.setData was not called"); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart new file mode 100644 index 000000000000..1684a367eb66 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -0,0 +1,122 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +typedef MethodCallCallback = dynamic Function(MethodCall methodCall); + +class MockFiledValue extends Mock implements FieldValueInterface {} + +const _kCollectionId = "test"; +const _kDocumentId = "document"; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + group("$MethodChannelDocumentReference()", () { + MethodChannelDocumentReference _documentReference; + final mockFieldValue = MockFiledValue(); + setUp(() { + _documentReference = MethodChannelDocumentReference( + FirestorePlatform.instance, [_kCollectionId, _kDocumentId]); + reset(mockFieldValue); + when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); + when(mockFieldValue.value).thenReturn(2.0); + }); + + test("setData", () async { + _assertSetDataMethodCalled(_documentReference, null, null); + _assertSetDataMethodCalled(_documentReference, true, null); + _assertSetDataMethodCalled(_documentReference, false, null); + _assertSetDataMethodCalled(_documentReference, false, mockFieldValue); + verify(mockFieldValue.instance); + }); + + test("updateData", () async { + bool isMethodCalled = false; + final Map data = {"test":"test","fieldValue": mockFieldValue}; + _handleMethodCall((call) { + if (call.method == "DocumentReference#updateData") { + isMethodCalled = true; + expect(call.arguments["data"]["test"], equals(data["test"])); + } + }); + await _documentReference.updateData(data); + verify(mockFieldValue.instance); + expect(isMethodCalled, isTrue, + reason: "DocumentReference.updateData was not called"); + }); + + test("get",() async { + await _assertGetMethodCalled(_documentReference, null, "default"); + await _assertGetMethodCalled(_documentReference, Source.cache, "cache"); + await _assertGetMethodCalled(_documentReference, Source.server, "server"); + await _assertGetMethodCalled(_documentReference, Source.serverAndCache, "default"); + }); + + test("delete", () async { + bool isMethodCalled = false; + _handleMethodCall((call) { + if(call.method == "DocumentReference#delete") { + isMethodCalled = true; + } + }); + await _documentReference.delete(); + expect(isMethodCalled, isTrue, + reason: "DocumentReference.delete was not called"); + }); + }); +} + +void _assertGetMethodCalled(DocumentReference documentReference,Source source, String expectedSourceString ) async { + bool isMethodCalled = false; + _handleMethodCall((call) { + if (call.method == "DocumentReference#get") { + isMethodCalled = true; + expect(call.arguments["source"], equals(expectedSourceString)); + } + return { + "path":"test/test", + "data": {}, + "metadata": { + "hasPendingWrites": false, + "isFromCache": false + } + }; + }); + if (source != null) { + await documentReference.get(source: source); + } else { + await documentReference.get(); + } + expect(isMethodCalled, isTrue, + reason: "DocumentReference.get was not called"); +} + +void _assertSetDataMethodCalled(DocumentReference documentReference, bool expectedMergeValue, FieldValueInterface fieldValue) async { + bool isMethodCalled = false; + final Map data = {"test":"test"}; + if(fieldValue != null) { + data.addAll({"fieldValue": fieldValue}); + } + _handleMethodCall((call) { + if (call.method == "DocumentReference#setData") { + isMethodCalled = true; + expect(call.arguments["data"]["test"], equals(data["test"])); + expect(call.arguments["options"]["merge"], expectedMergeValue ?? false); + } + }); + if (expectedMergeValue == null) { + await documentReference.setData(data); + } else { + await documentReference.setData(data,merge: expectedMergeValue); + } + expect(isMethodCalled, isTrue, + reason: "DocumentReference.setData was not called"); +} + +void _handleMethodCall(MethodCallCallback methodCallCallback) => + MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { + expect(call.arguments["app"], equals(FirestorePlatform.instance.appName())); + expect(call.arguments["path"], equals("$_kCollectionId/$_kDocumentId")); + return await methodCallCallback(call); + }); From efa315d0b66e9856cc495cf89073ff2614a1e3f8 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 14:43:12 +0000 Subject: [PATCH 068/144] added snapshot() unit test for document reference --- .../test/method_channel_document_reference.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 1684a367eb66..8f1f394cc941 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -64,6 +66,19 @@ void main() { expect(isMethodCalled, isTrue, reason: "DocumentReference.delete was not called"); }); + + test("snapshots", () async { + bool isMethodCalled = false; + _handleMethodCall((call) { + if(call.method == "DocumentReference#addSnapshotListener") { + isMethodCalled = true; + } + return 0; + }); + _documentReference.snapshots().listen((_){}); + expect(isMethodCalled, isTrue, + reason: "DocumentReference.addSnapshotListener was not called"); + }); }); } From b4fa2db8f667ce34f2285399361aaa05a0af7559 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 14:47:41 +0000 Subject: [PATCH 069/144] Added method_channel_field_value_factory_test --- ...thod_channel_field_value_factory_test.dart | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart new file mode 100644 index 000000000000..4d80fee0f149 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart @@ -0,0 +1,30 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group("$MethodChannelFieldValueFactory()", (){ + final MethodChannelFieldValueFactory factory = MethodChannelFieldValueFactory(); + test("arrayRemove", (){ + final actual = factory.arrayRemove([1]); + expect(actual.type, equals(FieldValueType.arrayRemove)); + }); + test("arrayUnion", (){ + final actual = factory.arrayUnion([1]); + expect(actual.type, equals(FieldValueType.arrayUnion)); + }); + test("delete", (){ + final actual = factory.delete(); + expect(actual.type, equals(FieldValueType.delete)); + }); + test("increment", (){ + final actualInt = factory.increment(1); + expect(actualInt.type, equals(FieldValueType.incrementInteger)); + final actualDouble = factory.increment(1.0); + expect(actualDouble.type, equals(FieldValueType.incrementDouble)); + }); + test("serverTimestamp", (){ + final actual = factory.serverTimestamp(); + expect(actual.type, equals(FieldValueType.serverTimestamp)); + }); + }); +} \ No newline at end of file From afd6b0e78afd60bc67e982216d32a24e1310b896 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 15:02:47 +0000 Subject: [PATCH 070/144] added transaction unit test --- .../test/test_common.dart | 0 .../test/transaction_test.dart | 93 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart new file mode 100644 index 000000000000..1806bba30501 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -0,0 +1,93 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; + +import 'test_common.dart'; + +class MockDocumentReference extends Mock implements DocumentReference {} + +class MockFiledValue extends Mock implements FieldValueInterface {} + +const _kTransactionId = 1022; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final mockFieldValue = MockFiledValue(); + + group("$Transaction()", (){ + Transaction transaction; + final mockDocumentReference = MockDocumentReference(); + when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); + setUp((){ + transaction = Transaction(_kTransactionId,FirestorePlatform.instance); + reset(mockFieldValue); + when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); + when(mockFieldValue.value).thenReturn(2.0); + }); + + test("get", () async { + bool isMethodCalled = false; + handleMethodCall((call){ + if(call.method == "Transaction#get") { + isMethodCalled = true; + expect(call.arguments["transactionId"], equals(_kTransactionId)); + } + }); + await transaction.get(mockDocumentReference); + expect(isMethodCalled, isTrue, + reason: "Transaction.get was not called"); + }); + + test("delete", () async { + bool isMethodCalled = false; + handleMethodCall((call){ + if(call.method == "Transaction#delete") { + isMethodCalled = true; + expect(call.arguments["transactionId"], equals(_kTransactionId)); + } + }); + await transaction.delete(mockDocumentReference); + expect(isMethodCalled, isTrue, + reason: "Transaction.delete was not called"); + }); + + test("update", () async { + bool isMethodCalled = false; + final Map data = { + "test": "test", + "fieldValue": mockFieldValue + }; + handleMethodCall((call) { + if (call.method == "Transaction#update") { + isMethodCalled = true; + expect(call.arguments["transactionId"], equals(_kTransactionId)); + expect(call.arguments["data"]["test"], equals(data["test"])); + } + }); + await transaction.update(mockDocumentReference,data); + verify(mockFieldValue.instance); + expect(isMethodCalled, isTrue, + reason: "Transaction#update was not called"); + }); + + test("set", () async { + bool isMethodCalled = false; + final Map data = { + "test": "test", + "fieldValue": mockFieldValue + }; + handleMethodCall((call) { + if (call.method == "Transaction#set") { + isMethodCalled = true; + expect(call.arguments["transactionId"], equals(_kTransactionId)); + expect(call.arguments["data"]["test"], equals(data["test"])); + } + }); + await transaction.set(mockDocumentReference,data); + verify(mockFieldValue.instance); + expect(isMethodCalled, isTrue, + reason: "Transaction#set was not called"); + }); + + }); +} \ No newline at end of file From 8860659e7ea77a5a1972e3dde3ad38c9155b711f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 15:03:06 +0000 Subject: [PATCH 071/144] Separated common testing logic --- .../method_channel_document_reference.dart | 63 ++++++++----------- .../test/test_common.dart | 15 +++++ 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 8f1f394cc941..f57890d85b28 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -1,25 +1,20 @@ -import 'dart:async'; - import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -typedef MethodCallCallback = dynamic Function(MethodCall methodCall); +import 'test_common.dart'; class MockFiledValue extends Mock implements FieldValueInterface {} -const _kCollectionId = "test"; -const _kDocumentId = "document"; - void main() { TestWidgetsFlutterBinding.ensureInitialized(); + group("$MethodChannelDocumentReference()", () { MethodChannelDocumentReference _documentReference; final mockFieldValue = MockFiledValue(); setUp(() { _documentReference = MethodChannelDocumentReference( - FirestorePlatform.instance, [_kCollectionId, _kDocumentId]); + FirestorePlatform.instance, [kCollectionId, kDocumentId]); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); @@ -35,8 +30,11 @@ void main() { test("updateData", () async { bool isMethodCalled = false; - final Map data = {"test":"test","fieldValue": mockFieldValue}; - _handleMethodCall((call) { + final Map data = { + "test": "test", + "fieldValue": mockFieldValue + }; + handleMethodCall((call) { if (call.method == "DocumentReference#updateData") { isMethodCalled = true; expect(call.arguments["data"]["test"], equals(data["test"])); @@ -48,17 +46,18 @@ void main() { reason: "DocumentReference.updateData was not called"); }); - test("get",() async { + test("get", () async { await _assertGetMethodCalled(_documentReference, null, "default"); await _assertGetMethodCalled(_documentReference, Source.cache, "cache"); await _assertGetMethodCalled(_documentReference, Source.server, "server"); - await _assertGetMethodCalled(_documentReference, Source.serverAndCache, "default"); + await _assertGetMethodCalled( + _documentReference, Source.serverAndCache, "default"); }); test("delete", () async { bool isMethodCalled = false; - _handleMethodCall((call) { - if(call.method == "DocumentReference#delete") { + handleMethodCall((call) { + if (call.method == "DocumentReference#delete") { isMethodCalled = true; } }); @@ -69,33 +68,31 @@ void main() { test("snapshots", () async { bool isMethodCalled = false; - _handleMethodCall((call) { - if(call.method == "DocumentReference#addSnapshotListener") { + handleMethodCall((call) { + if (call.method == "DocumentReference#addSnapshotListener") { isMethodCalled = true; } return 0; }); - _documentReference.snapshots().listen((_){}); + _documentReference.snapshots().listen((_) {}); expect(isMethodCalled, isTrue, reason: "DocumentReference.addSnapshotListener was not called"); }); }); } -void _assertGetMethodCalled(DocumentReference documentReference,Source source, String expectedSourceString ) async { +void _assertGetMethodCalled(DocumentReference documentReference, Source source, + String expectedSourceString) async { bool isMethodCalled = false; - _handleMethodCall((call) { + handleMethodCall((call) { if (call.method == "DocumentReference#get") { isMethodCalled = true; expect(call.arguments["source"], equals(expectedSourceString)); } return { - "path":"test/test", + "path": "test/test", "data": {}, - "metadata": { - "hasPendingWrites": false, - "isFromCache": false - } + "metadata": {"hasPendingWrites": false, "isFromCache": false} }; }); if (source != null) { @@ -107,13 +104,14 @@ void _assertGetMethodCalled(DocumentReference documentReference,Source source, S reason: "DocumentReference.get was not called"); } -void _assertSetDataMethodCalled(DocumentReference documentReference, bool expectedMergeValue, FieldValueInterface fieldValue) async { +void _assertSetDataMethodCalled(DocumentReference documentReference, + bool expectedMergeValue, FieldValueInterface fieldValue) async { bool isMethodCalled = false; - final Map data = {"test":"test"}; - if(fieldValue != null) { + final Map data = {"test": "test"}; + if (fieldValue != null) { data.addAll({"fieldValue": fieldValue}); } - _handleMethodCall((call) { + handleMethodCall((call) { if (call.method == "DocumentReference#setData") { isMethodCalled = true; expect(call.arguments["data"]["test"], equals(data["test"])); @@ -123,15 +121,8 @@ void _assertSetDataMethodCalled(DocumentReference documentReference, bool expect if (expectedMergeValue == null) { await documentReference.setData(data); } else { - await documentReference.setData(data,merge: expectedMergeValue); + await documentReference.setData(data, merge: expectedMergeValue); } expect(isMethodCalled, isTrue, reason: "DocumentReference.setData was not called"); } - -void _handleMethodCall(MethodCallCallback methodCallCallback) => - MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { - expect(call.arguments["app"], equals(FirestorePlatform.instance.appName())); - expect(call.arguments["path"], equals("$_kCollectionId/$_kDocumentId")); - return await methodCallCallback(call); - }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index e69de29bb2d1..e89d7f563482 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -0,0 +1,15 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +typedef MethodCallCallback = dynamic Function(MethodCall methodCall); + +const kCollectionId = "test"; +const kDocumentId = "document"; + +void handleMethodCall(MethodCallCallback methodCallCallback) => + MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { + expect(call.arguments["app"], equals(FirestorePlatform.instance.appName())); + expect(call.arguments["path"], equals("$kCollectionId/$kDocumentId")); + return await methodCallCallback(call); + }); \ No newline at end of file From cc2af37dd5bb2f6f189db3add144f3f384b2f091 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 15:03:19 +0000 Subject: [PATCH 072/144] use serve delegates in transaction --- .../lib/src/transaction.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index f696c22faabe..e05c6f77876d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -49,7 +49,7 @@ class Transaction extends TransactionPlatform { 'app': firestore.appName(), 'transactionId': _transactionId, 'path': documentReference.path, - 'data': data, + 'data': FieldValue.serverDelegates(data), }); } @@ -61,7 +61,7 @@ class Transaction extends TransactionPlatform { 'app': firestore.appName(), 'transactionId': _transactionId, 'path': documentReference.path, - 'data': data, + 'data': FieldValue.serverDelegates(data), }); } } From ade9dbf9ad8d4dcdc25c35745af226c671e84588 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 15:22:57 +0000 Subject: [PATCH 073/144] use serve delegates in write batch --- .../lib/src/write_batch.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart index d20a3897dc09..95ce41b96c0c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart @@ -62,7 +62,7 @@ class WriteBatch extends WriteBatchPlatform { 'app': _firestore.appName(), 'handle': handle, 'path': document.path, - 'data': data, + 'data': FieldValue.serverDelegates(data), 'options': {'merge': merge}, }, ), @@ -82,7 +82,7 @@ class WriteBatch extends WriteBatchPlatform { 'app': _firestore.appName(), 'handle': handle, 'path': document.path, - 'data': data, + 'data': FieldValue.serverDelegates(data) }, ), ); From 98d021ecf477f07cad932892009b0030d289a7b6 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 15:26:48 +0000 Subject: [PATCH 074/144] Formatting changes --- .../src/platform_interface/field_value.dart | 2 +- .../field_value_factory.dart | 1 - .../test/document_reference_test.dart | 20 ++++++++------ ...hod_channel_collection_reference_test.dart | 12 +++++---- ...thod_channel_field_value_factory_test.dart | 17 ++++++------ .../test/test_common.dart | 5 ++-- .../test/transaction_test.dart | 27 +++++++++---------- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 2f19f1fefb86..c012cfac6c40 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -23,7 +23,7 @@ class FieldValue implements FieldValueInterface { /// such as [FieldValue] @visibleForTesting static Map serverDelegates(Map data) { - if(data == null) { + if (data == null) { return null; } Map output = Map.from(data); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index c2c954cbba3e..fd64c6b08164 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -14,7 +14,6 @@ enum FieldValueType { /// An interface for a factory that is used to build [FieldValue] according to /// Platform (web or mobile) abstract class FieldValueFactory { - /// Current instance of [FieldValueFactory] static FieldValueFactory get instance => _instance; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart index 89a56bbbe973..4b6d14b4e00f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart @@ -3,13 +3,16 @@ import 'package:flutter_test/flutter_test.dart'; const _kCollectionId = "test"; const _kDocumentId = "document"; + class TestDocumentReference extends DocumentReference { - TestDocumentReference._(): super(FirestorePlatform.instance, [_kCollectionId,_kDocumentId]); + TestDocumentReference._() + : super(FirestorePlatform.instance, [_kCollectionId, _kDocumentId]); } + void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$DocumentReference()", (){ - test("Parent",(){ + group("$DocumentReference()", () { + test("Parent", () { final document = TestDocumentReference._(); final parent = document.parent(); final parentPath = parent.path; @@ -17,19 +20,20 @@ void main() { expect(parentPath, equals(_kCollectionId)); }); - test("documentID",(){ + test("documentID", () { final document = TestDocumentReference._(); expect(document.documentID, equals(_kDocumentId)); }); - test("Path",(){ + test("Path", () { final document = TestDocumentReference._(); expect(document.path, equals("$_kCollectionId/$_kDocumentId")); }); - test("Collection",(){ + test("Collection", () { final document = TestDocumentReference._(); - expect(document.collection("extra").path, equals("$_kCollectionId/$_kDocumentId/extra")); + expect(document.collection("extra").path, + equals("$_kCollectionId/$_kDocumentId/extra")); }); }); -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart index 4eabb5a3c4c7..ee650b499a11 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart @@ -26,10 +26,11 @@ void main() { expect(_testCollection.document(_kDocumentId).path.split("/").last, equals(_kDocumentId)); }); - test("Add",() async { + test("Add", () async { bool _methodChannelCalled = false; - MethodChannelFirestore.channel.setMockMethodCallHandler((MethodCall methodCall) async { - switch(methodCall.method) { + MethodChannelFirestore.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { case "DocumentReference#setData": expect(methodCall.arguments["data"]["test"], equals("test")); _methodChannelCalled = true; @@ -38,8 +39,9 @@ void main() { return; } }); - await _testCollection.add({"test":"test"}); - expect(_methodChannelCalled,isTrue, reason: "DocumentReference.setData was not called"); + await _testCollection.add({"test": "test"}); + expect(_methodChannelCalled, isTrue, + reason: "DocumentReference.setData was not called"); }); }); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart index 4d80fee0f149..f67d384e2eec 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart @@ -2,29 +2,30 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter_test/flutter_test.dart'; void main() { - group("$MethodChannelFieldValueFactory()", (){ - final MethodChannelFieldValueFactory factory = MethodChannelFieldValueFactory(); - test("arrayRemove", (){ + group("$MethodChannelFieldValueFactory()", () { + final MethodChannelFieldValueFactory factory = + MethodChannelFieldValueFactory(); + test("arrayRemove", () { final actual = factory.arrayRemove([1]); expect(actual.type, equals(FieldValueType.arrayRemove)); }); - test("arrayUnion", (){ + test("arrayUnion", () { final actual = factory.arrayUnion([1]); expect(actual.type, equals(FieldValueType.arrayUnion)); }); - test("delete", (){ + test("delete", () { final actual = factory.delete(); expect(actual.type, equals(FieldValueType.delete)); }); - test("increment", (){ + test("increment", () { final actualInt = factory.increment(1); expect(actualInt.type, equals(FieldValueType.incrementInteger)); final actualDouble = factory.increment(1.0); expect(actualDouble.type, equals(FieldValueType.incrementDouble)); }); - test("serverTimestamp", (){ + test("serverTimestamp", () { final actual = factory.serverTimestamp(); expect(actual.type, equals(FieldValueType.serverTimestamp)); }); }); -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index e89d7f563482..307c9b89f31d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -9,7 +9,8 @@ const kDocumentId = "document"; void handleMethodCall(MethodCallCallback methodCallCallback) => MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { - expect(call.arguments["app"], equals(FirestorePlatform.instance.appName())); + expect( + call.arguments["app"], equals(FirestorePlatform.instance.appName())); expect(call.arguments["path"], equals("$kCollectionId/$kDocumentId")); return await methodCallCallback(call); - }); \ No newline at end of file + }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 1806bba30501..1921e975c1ba 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -14,12 +14,12 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); final mockFieldValue = MockFiledValue(); - group("$Transaction()", (){ + group("$Transaction()", () { Transaction transaction; final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); - setUp((){ - transaction = Transaction(_kTransactionId,FirestorePlatform.instance); + setUp(() { + transaction = Transaction(_kTransactionId, FirestorePlatform.instance); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); @@ -27,21 +27,20 @@ void main() { test("get", () async { bool isMethodCalled = false; - handleMethodCall((call){ - if(call.method == "Transaction#get") { + handleMethodCall((call) { + if (call.method == "Transaction#get") { isMethodCalled = true; expect(call.arguments["transactionId"], equals(_kTransactionId)); } }); await transaction.get(mockDocumentReference); - expect(isMethodCalled, isTrue, - reason: "Transaction.get was not called"); + expect(isMethodCalled, isTrue, reason: "Transaction.get was not called"); }); test("delete", () async { bool isMethodCalled = false; - handleMethodCall((call){ - if(call.method == "Transaction#delete") { + handleMethodCall((call) { + if (call.method == "Transaction#delete") { isMethodCalled = true; expect(call.arguments["transactionId"], equals(_kTransactionId)); } @@ -64,7 +63,7 @@ void main() { expect(call.arguments["data"]["test"], equals(data["test"])); } }); - await transaction.update(mockDocumentReference,data); + await transaction.update(mockDocumentReference, data); verify(mockFieldValue.instance); expect(isMethodCalled, isTrue, reason: "Transaction#update was not called"); @@ -83,11 +82,9 @@ void main() { expect(call.arguments["data"]["test"], equals(data["test"])); } }); - await transaction.set(mockDocumentReference,data); + await transaction.set(mockDocumentReference, data); verify(mockFieldValue.instance); - expect(isMethodCalled, isTrue, - reason: "Transaction#set was not called"); + expect(isMethodCalled, isTrue, reason: "Transaction#set was not called"); }); - }); -} \ No newline at end of file +} From 6491ade58b69ad2e05f54c36d6620ecafa0d1e6f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 16:32:22 +0000 Subject: [PATCH 075/144] Started firestore_web tests --- .../cloud_firestore_web/pubspec.yaml | 1 + .../test/collection_reference_web_test.dart | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index f8415f84b312..407b35dc30e9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -27,6 +27,7 @@ dev_dependencies: flutter_test: sdk: flutter firebase_core_platform_interface: ^1.0.0 + firebase_core_web: ^0.1.1 environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart new file mode 100644 index 000000000000..83b72d6264a6 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -0,0 +1,44 @@ +@TestOn('chrome') +import 'dart:js' as js; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:firebase/firebase.dart' as web; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:firebase_core_web/firebase_core_web.dart'; +import 'package:flutter_test/flutter_test.dart'; + +const _kCollectionId = "test"; + +void main() { + group("$CollectionReferenceWeb()", () { + CollectionReferenceWeb collectionReference; + setUp((){ + final js.JsObject firebaseMock = js.JsObject.jsify({}); + js.context['firebase'] = firebaseMock; + js.context['firebase']['app'] = js.allowInterop((String name) { + return js.JsObject.jsify({ + 'name': name, + 'options': {'appId': '123'}, + }); + }); + js.context['firebase']['firestore'] = js.allowInterop((dynamic app) {}); + FirebaseCorePlatform.instance = FirebaseCoreWeb(); + FirestorePlatform.instance = FirestoreWeb(); + collectionReference = CollectionReferenceWeb(FirestorePlatform.instance , + web.firestore(web.app(FirestorePlatform.instance .appName())), + [_kCollectionId] + ); + }); + + test("parent",(){ + expect(collectionReference.parent(), isNull); + expect(CollectionReferenceWeb( + FirestorePlatform.instance , + web.firestore(web.app(FirestorePlatform.instance .appName())), + [_kCollectionId,_kCollectionId,_kCollectionId] + ), isInstanceOf()); + }); + }); +} \ No newline at end of file From 77f4318044bd6a85c2cabc7c6c4286739f11d244 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 20 Dec 2019 21:53:41 +0000 Subject: [PATCH 076/144] Completed collection_reference_web_test --- .../lib/collection_reference_web.dart | 44 ++--- .../lib/firestore_web.dart | 1 + .../cloud_firestore_web/lib/query_web.dart | 4 + .../cloud_firestore_web/pubspec.yaml | 1 + .../test/collection_reference_web_test.dart | 159 +++++++++++++++--- 5 files changed, 165 insertions(+), 44 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index c529d4931b14..6a1a78c3d95c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -1,14 +1,16 @@ part of cloud_firestore_web; +/// Web implementation for Firestore [CollectionReference] class CollectionReferenceWeb implements CollectionReference { final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; final List pathComponents; - QueryWeb _queryDelegate; + @visibleForTesting + QueryWeb queryDelegate; CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) - : _queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), + : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), webFirestore.collection(pathComponents.join("/"))); @override @@ -47,30 +49,30 @@ class CollectionReferenceWeb implements CollectionReference { } @override - Map buildArguments() => _queryDelegate.buildArguments(); + Map buildArguments() => queryDelegate.buildArguments(); @override Query endAt(List values) { _resetQueryDelegate(); - return _queryDelegate.endAt(values); + return queryDelegate.endAt(values); } @override Query endAtDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); - return _queryDelegate.endAtDocument(documentSnapshot); + return queryDelegate.endAtDocument(documentSnapshot); } @override Query endBefore(List values) { _resetQueryDelegate(); - return _queryDelegate.endBefore(values); + return queryDelegate.endBefore(values); } @override Query endBeforeDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); - return _queryDelegate.endBeforeDocument(documentSnapshot); + return queryDelegate.endBeforeDocument(documentSnapshot); } @override @@ -78,7 +80,7 @@ class CollectionReferenceWeb implements CollectionReference { @override Future getDocuments({Source source = Source.serverAndCache}) => - _queryDelegate.getDocuments(source: source); + queryDelegate.getDocuments(source: source); @override String get id => pathComponents.isEmpty ? null : pathComponents.last; @@ -89,50 +91,50 @@ class CollectionReferenceWeb implements CollectionReference { @override Query limit(int length) { _resetQueryDelegate(); - return _queryDelegate.limit(length); + return queryDelegate.limit(length); } @override Query orderBy(field, {bool descending = false}) { _resetQueryDelegate(); - return _queryDelegate.orderBy(field, descending: descending); + return queryDelegate.orderBy(field, descending: descending); } @override - Map get parameters => _queryDelegate.parameters; + Map get parameters => queryDelegate.parameters; @override String get path => pathComponents.join("/"); @override - CollectionReference reference() => _queryDelegate.reference(); + CollectionReference reference() => queryDelegate.reference(); @override Stream snapshots({bool includeMetadataChanges = false}) => - _queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); + queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); @override Query startAfter(List values) { _resetQueryDelegate(); - return _queryDelegate.startAfter(values); + return queryDelegate.startAfter(values); } @override Query startAfterDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); - return _queryDelegate.startAfterDocument(documentSnapshot); + return queryDelegate.startAfterDocument(documentSnapshot); } @override Query startAt(List values) { _resetQueryDelegate(); - return _queryDelegate.startAt(values); + return queryDelegate.startAt(values); } @override Query startAtDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); - return _queryDelegate.startAtDocument(documentSnapshot); + return queryDelegate.startAtDocument(documentSnapshot); } @override @@ -147,7 +149,7 @@ class CollectionReferenceWeb implements CollectionReference { List whereIn, bool isNull}) { _resetQueryDelegate(); - return _queryDelegate.where(field, + return queryDelegate.where(field, isEqualTo: isEqualTo, isLessThan: isLessThan, isLessThanOrEqualTo: isLessThanOrEqualTo, @@ -159,8 +161,6 @@ class CollectionReferenceWeb implements CollectionReference { isNull: isNull); } - void _resetQueryDelegate() { - _queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), - webFirestore.collection(pathComponents.join("/"))); - } + void _resetQueryDelegate() => + queryDelegate = queryDelegate.resetQueryDelegate(); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 91a5b6cfdeee..96ee24385210 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -6,6 +6,7 @@ import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; part 'collection_reference_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 5d8b1418292b..b360c9b29cbc 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -249,4 +249,8 @@ class QueryWeb implements Query { @override Map get parameters => Map(); + + @visibleForTesting + QueryWeb resetQueryDelegate() => + QueryWeb(firestore, pathComponents.join("/"), webQuery); } diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index 407b35dc30e9..c77a80ec29ea 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -28,6 +28,7 @@ dev_dependencies: sdk: flutter firebase_core_platform_interface: ^1.0.0 firebase_core_web: ^0.1.1 + mockito: ^4.1.1 environment: sdk: ">=2.1.0 <3.0.0" diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index 83b72d6264a6..80ab8cc5069f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -3,42 +3,157 @@ import 'dart:js' as js; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:firebase/firebase.dart' as web; -import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase/firestore.dart' as web; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; import 'package:firebase_core_web/firebase_core_web.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; const _kCollectionId = "test"; +class MockFirestoreWeb extends Mock implements web.Firestore {} + +class MockDocumentReference extends Mock implements web.DocumentReference {} + +class MockQueryWeb extends Mock implements QueryWeb {} + +class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} + void main() { group("$CollectionReferenceWeb()", () { + final mockFirestoreWeb = MockFirestoreWeb(); + final mockDocumentReference = MockDocumentReference(); CollectionReferenceWeb collectionReference; - setUp((){ - final js.JsObject firebaseMock = js.JsObject.jsify({}); - js.context['firebase'] = firebaseMock; - js.context['firebase']['app'] = js.allowInterop((String name) { - return js.JsObject.jsify({ - 'name': name, - 'options': {'appId': '123'}, - }); + setUp(() { + final js.JsObject firebaseMock = js.JsObject.jsify({ + 'firestore': js.allowInterop((_) => mockFirestoreWeb), + 'app': js.allowInterop((String name) { + return js.JsObject.jsify({ + 'name': name, + 'options': {'appId': '123'}, + }); + }) }); - js.context['firebase']['firestore'] = js.allowInterop((dynamic app) {}); + js.context['firebase'] = firebaseMock; FirebaseCorePlatform.instance = FirebaseCoreWeb(); FirestorePlatform.instance = FirestoreWeb(); - collectionReference = CollectionReferenceWeb(FirestorePlatform.instance , - web.firestore(web.app(FirestorePlatform.instance .appName())), - [_kCollectionId] - ); + collectionReference = CollectionReferenceWeb(FirestorePlatform.instance, + js.context['firebase']['firestore'](""), [_kCollectionId]); + collectionReference.queryDelegate = MockQueryWeb(); + when(mockFirestoreWeb.doc(any)).thenReturn(mockDocumentReference); + when(collectionReference.queryDelegate.resetQueryDelegate()) + .thenReturn(collectionReference.queryDelegate); }); - test("parent",(){ + test("parent", () { expect(collectionReference.parent(), isNull); - expect(CollectionReferenceWeb( - FirestorePlatform.instance , - web.firestore(web.app(FirestorePlatform.instance .appName())), - [_kCollectionId,_kCollectionId,_kCollectionId] - ), isInstanceOf()); + expect( + CollectionReferenceWeb( + FirestorePlatform.instance, + js.context['firebase']['firestore'](""), + [_kCollectionId, _kCollectionId, _kCollectionId]).parent(), + isInstanceOf()); + }); + + test("document", () { + final newDocument = collectionReference.document(); + expect(newDocument.path.split("/").length, + collectionReference.pathComponents.length + 1); + final newDocumentWithPath = collectionReference.document("test1"); + expect(newDocumentWithPath.path, + equals("${collectionReference.path}/test1")); + }); + + test("add", () async { + expect(await collectionReference.add({}), + isInstanceOf()); + }); + + test("buildArguments", () async { + collectionReference.buildArguments(); + verify(collectionReference.queryDelegate.buildArguments()); + }); + + test("getDocuments", () async { + await collectionReference.getDocuments(); + verify(collectionReference.queryDelegate.getDocuments()); + }); + + test("reference", () async { + collectionReference.reference(); + verify(collectionReference.queryDelegate.reference()); + }); + + test("snapshots", () async { + collectionReference.snapshots(includeMetadataChanges: true); + verify(collectionReference.queryDelegate + .snapshots(includeMetadataChanges: true)); + collectionReference.snapshots(includeMetadataChanges: false); + verify(collectionReference.queryDelegate + .snapshots(includeMetadataChanges: false)); + }); + + test("where", () async { + collectionReference.where("test"); + verify(collectionReference.queryDelegate.where("test")); + }); + + test("startAt", () async { + collectionReference.startAt([]); + verify(collectionReference.queryDelegate.startAt([])); + }); + + test("startAfter", () async { + collectionReference.startAfter([]); + verify(collectionReference.queryDelegate.startAfter([])); + }); + + test("endBefore", () async { + collectionReference.endBefore([]); + verify(collectionReference.queryDelegate.endBefore([])); + }); + + test("endAt", () async { + collectionReference.endAt([]); + verify(collectionReference.queryDelegate.endAt([])); + }); + + test("limit", () async { + collectionReference.limit(1); + verify(collectionReference.queryDelegate.limit(1)); + }); + + test("orderBy", () async { + collectionReference.orderBy("test"); + verify(collectionReference.queryDelegate.orderBy("test")); + collectionReference.orderBy("test", descending: true); + verify( + collectionReference.queryDelegate.orderBy("test", descending: true)); + }); + + test("startAfterDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.startAfterDocument(mockSnapshot); + verify( + collectionReference.queryDelegate.startAfterDocument(mockSnapshot)); + }); + + test("startAtDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.startAtDocument(mockSnapshot); + verify(collectionReference.queryDelegate.startAtDocument(mockSnapshot)); + }); + + test("endBeforeDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.endBeforeDocument(mockSnapshot); + verify(collectionReference.queryDelegate.endBeforeDocument(mockSnapshot)); + }); + + test("endAtDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.endAtDocument(mockSnapshot); + verify(collectionReference.queryDelegate.endAtDocument(mockSnapshot)); }); }); -} \ No newline at end of file +} From 118780d7d023affb4c870720920aef363721562d Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 00:15:35 +0000 Subject: [PATCH 077/144] Avoid storing non-default Firestore app as static instance --- .../cloud_firestore/lib/src/document_reference.dart | 3 ++- .../cloud_firestore/lib/src/document_snapshot.dart | 3 ++- .../cloud_firestore/lib/src/firestore.dart | 9 +++++---- .../cloud_firestore/cloud_firestore/lib/src/query.dart | 3 ++- .../lib/cloud_firestore_platform_interface.dart | 3 +-- .../lib/src/document_snapshot.dart | 6 +++--- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index c807f7663b5c..2fac0defe569 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -15,7 +15,8 @@ class DocumentReference { DocumentReference._(this._delegate); /// The Firestore instance associated with this document reference - Firestore get firestore => Firestore.instance; + Firestore get firestore => + Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); @override bool operator ==(dynamic o) => diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 6d2df1b49f60..4d7e66c7684e 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -11,7 +11,8 @@ part of cloud_firestore; /// syntax to access a specific field. class DocumentSnapshot { platform.DocumentSnapshot _delegate; - Firestore _firestore = Firestore.instance; + Firestore get _firestore => + Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); DocumentSnapshot._(this._delegate); /// The reference that produced this snapshot diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 5c874540b44a..0d4fdbd30870 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -16,14 +16,15 @@ class Firestore { return _delegatePackingProperty; } - Firestore({FirebaseApp app, platform.FirestorePlatform delegate}) - : _delegatePackingProperty = delegate; + Firestore({FirebaseApp app}) + : _delegatePackingProperty = app != null + ? platform.FirestorePlatform.withApp(app: app) + : platform.FirestorePlatform.instance; static MethodChannel get channel => platform.MethodChannelFirestore.channel; /// Gets the instance of Firestore for the default Firebase app. - static Firestore get instance => - Firestore(delegate: platform.FirestorePlatform.instance); + static Firestore get instance => Firestore(); /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. /// diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 7502c284870e..ce1bd2b8ab69 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -11,7 +11,8 @@ class Query { Query._(this._delegate); /// The Firestore instance associated with this query - Firestore get firestore => Firestore.instance; + Firestore get firestore => + Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); List get _pathComponents => _delegate.pathComponents; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 332ad284ef68..0d85ecc2f9cb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -51,8 +51,7 @@ abstract class FirestorePlatform extends PlatformInterface { static final Object _token = Object(); factory FirestorePlatform.withApp({FirebaseApp app}) { - FirestorePlatform.instance = FirestorePlatform.instance.withApp(app); - return FirestorePlatform.instance; + return FirestorePlatform.instance.withApp(app); } static FirestorePlatform get instance { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index ffdcca53185c..4810cd1aaf09 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -10,13 +10,13 @@ part of cloud_firestore_platform_interface; /// The data can be extracted with the data property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { - DocumentSnapshot(this._path, this.data, this.metadata, this._firestore); + DocumentSnapshot(this._path, this.data, this.metadata, this.firestore); final String _path; - final FirestorePlatform _firestore; + final FirestorePlatform firestore; /// The reference that produced this snapshot - DocumentReference get reference => _firestore.document(_path); + DocumentReference get reference => firestore.document(_path); /// Contains all the data of this snapshot final Map data; From e4519d4a2be3d0b82b0efcd8872abfc14a0c670f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 00:27:33 +0000 Subject: [PATCH 078/144] Fixed method_channel_transaction --- .../lib/src/method_channel_firestore.dart | 2 +- .../lib/src/transaction.dart | 5 +++-- .../test/method_channel_cloud_firestore_test.dart | 2 +- .../test/transaction_test.dart | 2 +- .../cloud_firestore_web/lib/transaction_web.dart | 3 +++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index c7783fe75d3e..f212585e3e70 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -27,7 +27,7 @@ class MethodChannelFirestore extends FirestorePlatform { _documentObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; - final Transaction transaction = Transaction(transactionId, this); + final Transaction transaction = Transaction(transactionId, call.arguments["app"]); final dynamic result = await _transactionHandlers[transactionId](transaction); await transaction.finish(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index e05c6f77876d..c50ddc99f627 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -5,9 +5,10 @@ part of cloud_firestore_platform_interface; class Transaction extends TransactionPlatform { + final String appName; @visibleForTesting - Transaction(int transactionId, FirestorePlatform firestore) - : super(transactionId, firestore); + Transaction(int transactionId, this.appName) + : super(transactionId, appName == FirebaseApp.defaultAppName ? FirestorePlatform.instance : FirestorePlatform.withApp(app: FirebaseApp(name: appName))); Future finish() => Future.wait(_pendingResults); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index f495fb2259b3..601b3029d4cd 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -47,7 +47,7 @@ void main() { firestore = MethodChannelFirestore(app: app); collectionReference = firestore.collection('foo'); collectionGroupQuery = firestore.collectionGroup('bar'); - transaction = Transaction(0, firestore); + transaction = Transaction(0, firestore.appName()); MethodChannelFirestore.channel .setMockMethodCallHandler((MethodCall methodCall) async { log.add(methodCall); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 1921e975c1ba..b7c54bd840c0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -19,7 +19,7 @@ void main() { final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); setUp(() { - transaction = Transaction(_kTransactionId, FirestorePlatform.instance); + transaction = Transaction(_kTransactionId, FirestorePlatform.instance.appName()); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 8f58d0885c43..f22b6cd3fca2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -7,6 +7,9 @@ class TransactionWeb implements Transaction { TransactionWeb._(this._webTransaction, this.firestore); + @override + String get appName => firestore.appName(); + @override Future delete(DocumentReference documentReference) async { assert(documentReference is DocumentReferenceWeb); From e26a8122aca7df9e1a61d0df75dd1fd97abce046 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 00:32:27 +0000 Subject: [PATCH 079/144] Check for null data in codec_utility --- .../cloud_firestore_web/lib/utils/codec_utility.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 3b5831778da5..8ac4490843c4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -35,12 +35,18 @@ class _CodecUtility { } static Map decodeMapData(Map data) { + if (data == null) { + return null; + } Map output = Map.from(data); output.updateAll((key, value) => valueDecode(value)); return output; } static List decodeArrayData(List data) { + if (data == null) { + return null; + } return List.from(data).map(valueDecode).toList(); } From f8bc03567f03f9cb21f73e67a7f62cee2d98028f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 17:10:47 +0000 Subject: [PATCH 080/144] Unit test firestore_web --- .../analysis_options.yaml | 7 -- .../cloud_firestore_platform_interface.dart | 2 +- .../lib/src/blob.dart | 1 + .../lib/src/document_snapshot.dart | 3 + .../lib/src/field_path.dart | 2 + .../lib/src/firestore_message_codec.dart | 4 ++ .../lib/src/geo_point.dart | 1 + .../method_channel_collection_reference.dart | 1 + .../src/method_channel_document_change.dart | 5 +- .../method_channel_document_reference.dart | 3 + .../method_channel_field_value_factory.dart | 2 + .../lib/src/method_channel_firestore.dart | 5 +- .../lib/src/method_channel_query.dart | 13 ++-- .../src/method_channel_query_snapshot.dart | 1 + .../collection_reference.dart | 1 + .../platform_interface/document_change.dart | 1 + .../document_reference_interface.dart | 4 +- .../field_value_factory.dart | 11 +++ .../lib/src/platform_interface/query.dart | 1 + .../platform_interface/query_snapshot.dart | 1 + .../lib/src/snapshot_metadata.dart | 1 + .../lib/src/timestamp.dart | 10 +++ .../lib/src/transaction.dart | 13 +++- .../src/transaction_platform_interface.dart | 7 ++ .../lib/src/utils/auto_id_generator.dart | 1 + .../lib/src/write_batch.dart | 1 + .../test/field_value_test.dart | 2 +- .../method_channel_cloud_firestore_test.dart | 33 +++++---- .../test/transaction_test.dart | 3 +- .../cloud_firestore_web/analysis_options.yaml | 7 -- .../lib/document_reference_web.dart | 8 ++- .../lib/transaction_web.dart | 6 +- .../lib/utils/codec_utility.dart | 3 +- .../lib/write_batch_web.dart | 4 +- .../test/collection_reference_web_test.dart | 32 ++------- .../test/document_reference_web_test.dart | 71 +++++++++++++++++++ .../cloud_firestore_web/test/test_common.dart | 34 +++++++++ 37 files changed, 228 insertions(+), 77 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml delete mode 100644 packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/test_common.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml deleted file mode 100644 index 880f38c52a83..000000000000 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/analysis_options.yaml +++ /dev/null @@ -1,7 +0,0 @@ -include: ../../../analysis_options.yaml - -analyzer: - errors: - curly_braces_in_flow_control_structures: ignore - public_member_api_docs: ignore - unawaited_futures: ignore diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 0d85ecc2f9cb..ca060d6176a0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -69,7 +69,7 @@ abstract class FirestorePlatform extends PlatformInterface { } FirestorePlatform withApp(FirebaseApp app) { - throw UnimplementedError("_withApp() not implemented"); + throw UnimplementedError("withApp() not implemented"); } String appName() { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index 26c09fe19356..d66aaf2eb7ee 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -2,6 +2,7 @@ part of cloud_firestore_platform_interface; /// Represents binary data stored in [Uint8List] class Blob { + /// Create a [Blob] const Blob(this.bytes); /// Blob Data bytes diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index 4810cd1aaf09..d4c9fe81b6b2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -10,9 +10,12 @@ part of cloud_firestore_platform_interface; /// The data can be extracted with the data property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { + /// Create instance of [DocumentSnapshot] DocumentSnapshot(this._path, this.data, this.metadata, this.firestore); final String _path; + + /// instance of the underlying [FirestorePlatform] app used final FirestorePlatform firestore; /// The reference that produced this snapshot diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index f3cd6c8ba205..a611dc5d42f0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -13,6 +13,8 @@ class FieldPath { const FieldPath._(this.type); @visibleForTesting + // ignoring lint rule here as it's only visible for testing + // ignore: public_member_api_docs final _FieldPathType type; /// The path to the document id, which can be used in queries. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index 3397ea50b653..dc6569668610 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -5,7 +5,11 @@ part of cloud_firestore_platform_interface; @visibleForTesting +// ignoring lint rule here as it's only visible for testing +// ignore: public_member_api_docs class FirestoreMessageCodec extends StandardMessageCodec { + // ignoring lint rule here as it's only visible for testing + // ignore: public_member_api_docs const FirestoreMessageCodec(); static const int _kDateTime = 128; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart index 7f7b13ab9e46..c54f7e5cb462 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// Represents a geographical point by its longitude and latitude class GeoPoint { + /// Create [GeoPoint] instance const GeoPoint(this.latitude, this.longitude); final double latitude; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart index ed43a00cda09..5848d0ff2669 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart @@ -9,6 +9,7 @@ part of cloud_firestore_platform_interface; /// inherited from [Query]). class MethodChannelCollectionReference extends MethodChannelQuery implements CollectionReference { + /// Create a [MethodChannelCollectionReference] from [pathComponents] MethodChannelCollectionReference( FirestorePlatform firestore, List pathComponents) : super(firestore: firestore, pathComponents: pathComponents); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart index 5313e32a714a..477e10d7c014 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart @@ -9,6 +9,7 @@ part of cloud_firestore_platform_interface; /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class MethodChannelDocumentChange extends DocumentChange { + /// Create instance of [MethodChannelDocumentChange] using [data] MethodChannelDocumentChange( Map data, FirestorePlatform firestore) : super(DocumentChangeType.values.firstWhere((DocumentChangeType type) { @@ -19,8 +20,8 @@ class MethodChannelDocumentChange extends DocumentChange { DocumentSnapshot( data['path'], _asStringKeyedMap(data['document']), - SnapshotMetadata(data["metadata"]["hasPendingWrites"], - data["metadata"]["isFromCache"]), + SnapshotMetadata(data['etadata']['hasPendingWrites'], + data['metadata']['isFromCache']), firestore, )); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart index db7ff4150aa6..0f3b5f3566f2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart @@ -4,7 +4,10 @@ part of cloud_firestore_platform_interface; +/// A [MethodChannelDocumentReference] is an implementation of [DocumentReference] +/// that uses [MethodChannel] to communicate with Firebase plugins class MethodChannelDocumentReference extends DocumentReference { + /// Create a [MethodChannelDocumentReference] from [pathComponents] MethodChannelDocumentReference( FirestorePlatform firestore, List pathComponents) : assert(firestore != null), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart index f6a9461b00b7..8e771fe00cda 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart @@ -1,5 +1,7 @@ part of cloud_firestore_platform_interface; +/// An implementation of [FieldValueFactory] that is suitable to be used +/// on mobile where communication relies on [MethodChannel] class MethodChannelFieldValueFactory implements FieldValueFactory { @override FieldValue arrayRemove(List elements) => diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index f212585e3e70..34aa3269dc14 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -8,6 +8,7 @@ part of cloud_firestore_platform_interface; /// /// You can get an instance by calling [Firestore.instance]. class MethodChannelFirestore extends FirestorePlatform { + /// Create an instance of [MethodChannelFirestore] with optional [FirebaseApp] MethodChannelFirestore({FirebaseApp app}) : super(app: app ?? FirebaseApp.instance) { if (_initialized) return; @@ -27,7 +28,8 @@ class MethodChannelFirestore extends FirestorePlatform { _documentObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; - final Transaction transaction = Transaction(transactionId, call.arguments["app"]); + final Transaction transaction = + Transaction(transactionId, call.arguments["app"]); final dynamic result = await _transactionHandlers[transactionId](transaction); await transaction.finish(); @@ -43,6 +45,7 @@ class MethodChannelFirestore extends FirestorePlatform { static bool _initialized = false; + /// [MethodChannel] used to communicate with the native plugin static const MethodChannel channel = MethodChannel( 'plugins.flutter.io/cloud_firestore', StandardMethodCodec(FirestoreMessageCodec()), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart index 727ac3c1a350..b2bbcec63f36 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. class MethodChannelQuery extends Query { + /// Create a [MethodChannelQuery] from [pathComponents] MethodChannelQuery( {@required FirestorePlatform firestore, @required List pathComponents, @@ -120,15 +121,19 @@ class MethodChannelQuery extends Query { if (isEqualTo != null) addCondition(field, '==', isEqualTo); if (isLessThan != null) addCondition(field, '<', isLessThan); - if (isLessThanOrEqualTo != null) + if (isLessThanOrEqualTo != null) { addCondition(field, '<=', isLessThanOrEqualTo); + } if (isGreaterThan != null) addCondition(field, '>', isGreaterThan); - if (isGreaterThanOrEqualTo != null) + if (isGreaterThanOrEqualTo != null) { addCondition(field, '>=', isGreaterThanOrEqualTo); - if (arrayContains != null) + } + if (arrayContains != null) { addCondition(field, 'array-contains', arrayContains); - if (arrayContainsAny != null) + } + if (arrayContainsAny != null) { addCondition(field, 'array-contains-any', arrayContainsAny); + } if (whereIn != null) addCondition(field, 'in', whereIn); if (isNull != null) { assert( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart index 490b382073e5..9faa7b7c3c43 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class MethodChannelQuerySnapshot extends QuerySnapshot { + /// Creates a [MethodChannelQuerySnapshot] from the given [data] MethodChannelQuerySnapshot( Map data, FirestorePlatform firestore) : super( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index 05ae612cdba7..f10e47d00423 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -8,6 +8,7 @@ part of cloud_firestore_platform_interface; /// document references, and querying for documents (using the methods /// inherited from [Query]). abstract class CollectionReference extends Query { + /// Create a [CollectionReference] using [pathComponents] CollectionReference(FirestorePlatform firestore, List pathComponents) : super(firestore: firestore, pathComponents: pathComponents); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 5a7bd4bf750b..10baa78f6e28 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -23,6 +23,7 @@ enum DocumentChangeType { /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class DocumentChange { + /// Create a [DocumentChange] DocumentChange(this.type, this.oldIndex, this.newIndex, this.document); /// The type of change that occurred (added, modified, or removed). diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart index 9efb650b1ba2..5960e27aea31 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart @@ -70,9 +70,7 @@ abstract class DocumentReference { /// Returns the reference of a collection contained inside of this /// document. CollectionReference collection(String collectionPath) { - return firestore.collection( - [path, collectionPath].join('/'), - ); + return firestore.collection('$path/$collectionPath'); } /// Notifies of documents at this location diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index fd64c6b08164..6118a3770d23 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -3,11 +3,22 @@ part of cloud_firestore_platform_interface; /// Sentinel values that can be used when writing document fields with set() or /// update(). enum FieldValueType { + /// adds elements to an array but only elements not already present arrayUnion, + + /// removes all instances of each given element arrayRemove, + + /// deletes field delete, + + /// sets field value to server timestamp serverTimestamp, + + /// increment or decrement a numeric field value using a double value incrementDouble, + + /// increment or decrement a numeric field value using an integer value incrementInteger, } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 7c837d8cbc98..0266c675a68a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. abstract class Query { + /// Create a [Query] instance Query( {@required this.firestore, @required List pathComponents, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 9b54a6cc3c67..48d7e767ce07 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { + /// Create a [QuerySnapshot] QuerySnapshot(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart index 2f9a6104a9e5..8984e744d604 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart @@ -6,6 +6,7 @@ part of cloud_firestore_platform_interface; /// Metadata about a snapshot, describing the state of the snapshot. class SnapshotMetadata { + /// Create an instance of [SnapshotMetadata] SnapshotMetadata(this.hasPendingWrites, this.isFromCache); /// Whether the snapshot contains the result of local writes that have not yet diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart index 06700468aa54..26411f2e680d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart @@ -25,26 +25,31 @@ void _check(bool expr, String name, int value) { /// /// For more information, see [the reference timestamp definition](https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto) class Timestamp implements Comparable { + /// Creates a [Timestamp] Timestamp(this._seconds, this._nanoseconds) { _validateRange(_seconds, _nanoseconds); } + /// Create a [Timestamp] fromMillisecondsSinceEpoch factory Timestamp.fromMillisecondsSinceEpoch(int milliseconds) { final int seconds = (milliseconds / _kThousand).floor(); final int nanoseconds = (milliseconds - seconds * _kThousand) * _kMillion; return Timestamp(seconds, nanoseconds); } + /// Create a [Timestamp] fromMicrosecondsSinceEpoch factory Timestamp.fromMicrosecondsSinceEpoch(int microseconds) { final int seconds = (microseconds / _kMillion).floor(); final int nanoseconds = (microseconds - seconds * _kMillion) * _kThousand; return Timestamp(seconds, nanoseconds); } + /// Create a [Timestamp] from [DateTime] instance factory Timestamp.fromDate(DateTime date) { return Timestamp.fromMicrosecondsSinceEpoch(date.microsecondsSinceEpoch); } + /// Create a [Timestamp] from [DateTime].now() factory Timestamp.now() { return Timestamp.fromMicrosecondsSinceEpoch( DateTime.now().microsecondsSinceEpoch); @@ -56,16 +61,21 @@ class Timestamp implements Comparable { static const int _kStartOfTime = -62135596800; static const int _kEndOfTime = 253402300800; + // ignore: public_member_api_docs int get seconds => _seconds; + // ignore: public_member_api_docs int get nanoseconds => _nanoseconds; + // ignore: public_member_api_docs int get millisecondsSinceEpoch => (seconds * _kThousand + nanoseconds / _kMillion).floor(); + // ignore: public_member_api_docs int get microsecondsSinceEpoch => (seconds * _kMillion + nanoseconds / _kThousand).floor(); + /// Converts [Timestamp] to [DateTime] DateTime toDate() { return DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index c50ddc99f627..578c8405205f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -4,12 +4,23 @@ part of cloud_firestore_platform_interface; +/// An implementation of [TransactionPlatform] which uses [MethodChannel] to +/// communication with native plugin class Transaction extends TransactionPlatform { + /// [FirebaseApp] name used for this [Transaction] final String appName; + + // disabling lint as it's only visible for testing + // ignore: public_member_api_docs @visibleForTesting Transaction(int transactionId, this.appName) - : super(transactionId, appName == FirebaseApp.defaultAppName ? FirestorePlatform.instance : FirestorePlatform.withApp(app: FirebaseApp(name: appName))); + : super( + transactionId, + appName == FirebaseApp.defaultAppName + ? FirestorePlatform.instance + : FirestorePlatform.withApp(app: FirebaseApp(name: appName))); + /// executes all the pending operations on the transaction Future finish() => Future.wait(_pendingResults); @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart index 42e4f272580e..4c0e0aa514f4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -4,13 +4,20 @@ part of cloud_firestore_platform_interface; +/// The TransactionHandler may be executed multiple times, it should be able +/// to handle multiple executions. typedef Future TransactionHandler(Transaction transaction); +/// a [TransactionPlatform] is a set of read and write operations on one or more documents. abstract class TransactionPlatform { + // disabling lint as it's only visible for testing + // ignore: public_member_api_docs @visibleForTesting TransactionPlatform(this._transactionId, this.firestore); int _transactionId; + + /// [FirestorePlatform] instance used for this [TransactionPlatform] FirestorePlatform firestore; List> _pendingResults = >[]; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart index ea21cbea5cc5..21485851c177 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart @@ -21,6 +21,7 @@ class AutoIdGenerator { static final Random _random = Random(); + /// Automatically Generates a random new Id static String autoId() { final StringBuffer stringBuffer = StringBuffer(); final int maxRandom = _AUTO_ID_ALPHABET.length; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart index 95ce41b96c0c..2b3da0101632 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart @@ -11,6 +11,7 @@ part of cloud_firestore_platform_interface; /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. class WriteBatch extends WriteBatchPlatform { + /// Create an instance of [WriteBatch] WriteBatch(this._firestore) : _handle = MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#create', diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart index 4d1b8099c13f..3e9106d2ada8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -7,7 +7,7 @@ class MockFieldValue extends Mock implements FieldValueInterface {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); group("$FieldValue()", () { - test("ServeDelegates", () { + test("serverDelegates", () { expect(FieldValue.serverDelegates(null), isNull); final mockFieldValue = MockFieldValue(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 601b3029d4cd..68d495be6a87 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -56,6 +56,7 @@ void main() { final int handle = mockHandleId++; // Wait before sending a message back. // Otherwise the first request didn't have the time to finish. + // ignore: unawaited_futures Future.delayed(Duration.zero).then((_) { // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. // https://github.com/flutter/flutter/issues/33446 @@ -89,6 +90,7 @@ void main() { final int handle = mockHandleId++; // Wait before sending a message back. // Otherwise the first request didn't have the time to finish. + // ignore: unawaited_futures Future.delayed(Duration.zero).then((_) { // TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable. // https://github.com/flutter/flutter/issues/33446 @@ -370,7 +372,7 @@ void main() { .where('createdAt', isLessThan: 100) .snapshots() .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); + subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( log, @@ -403,7 +405,7 @@ void main() { .where('country', whereIn: ['USA', 'Japan']) .snapshots() .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); + subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( log, @@ -441,7 +443,7 @@ void main() { arrayContainsAny: ['west-coast', 'east-coast']) .snapshots() .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); + subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( log, @@ -478,7 +480,7 @@ void main() { .where('profile', isNull: true) .snapshots() .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); + subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( log, @@ -511,7 +513,7 @@ void main() { .orderBy('createdAt') .snapshots() .listen((QuerySnapshot querySnapshot) {}); - subscription.cancel(); + subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( log, @@ -1387,16 +1389,18 @@ void _checkEncodeDecode(MessageCodec codec, T message) { } bool _deepEquals(dynamic valueA, dynamic valueB) { - if (valueA is TypedData) + if (valueA is TypedData) { return valueB is TypedData && _deepEqualsTypedData(valueA, valueB); + } if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; if (valueA is FieldValue) { return valueB is FieldValue && _deepEqualsFieldValue(valueA, valueB); } - if (valueA is FieldPath) + if (valueA is FieldPath) { return valueB is FieldPath && valueA.type == valueB.type; + } return valueA == valueB; } @@ -1406,14 +1410,18 @@ bool _deepEqualsTypedData(TypedData valueA, TypedData valueB) { _deepEqualsList( valueA.buffer.asUint8List(), valueB.buffer.asUint8List()); } - if (valueA is Uint8List) + if (valueA is Uint8List) { return valueB is Uint8List && _deepEqualsList(valueA, valueB); - if (valueA is Int32List) + } + if (valueA is Int32List) { return valueB is Int32List && _deepEqualsList(valueA, valueB); - if (valueA is Int64List) + } + if (valueA is Int64List) { return valueB is Int64List && _deepEqualsList(valueA, valueB); - if (valueA is Float64List) + } + if (valueA is Float64List) { return valueB is Float64List && _deepEqualsList(valueA, valueB); + } throw 'Unexpected typed data: $valueA'; } @@ -1429,8 +1437,9 @@ bool _deepEqualsMap( Map valueA, Map valueB) { if (valueA.length != valueB.length) return false; for (final dynamic key in valueA.keys) { - if (!valueB.containsKey(key) || !_deepEquals(valueA[key], valueB[key])) + if (!valueB.containsKey(key) || !_deepEquals(valueA[key], valueB[key])) { return false; + } } return true; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index b7c54bd840c0..8b24bd0fd455 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -19,7 +19,8 @@ void main() { final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); setUp(() { - transaction = Transaction(_kTransactionId, FirestorePlatform.instance.appName()); + transaction = + Transaction(_kTransactionId, FirestorePlatform.instance.appName()); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); diff --git a/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml b/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml deleted file mode 100644 index 880f38c52a83..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/analysis_options.yaml +++ /dev/null @@ -1,7 +0,0 @@ -include: ../../../analysis_options.yaml - -analyzer: - errors: - curly_braces_in_flow_control_structures: ignore - public_member_api_docs: ignore - unawaited_futures: ignore diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 54004700a485..d8f3638f9d6b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -1,5 +1,6 @@ part of cloud_firestore_web; +/// Web implementation for firestore [DocumentReference] class DocumentReferenceWeb extends DocumentReference { final web.Firestore firestoreWeb; final web.DocumentReference delegate; @@ -12,11 +13,11 @@ class DocumentReferenceWeb extends DocumentReference { @override Future setData(Map data, {bool merge = false}) => delegate.set( - _CodecUtility.encodeMapData(data), web.SetOptions(merge: merge)); + CodecUtility.encodeMapData(data), web.SetOptions(merge: merge)); @override Future updateData(Map data) => - delegate.update(data: _CodecUtility.encodeMapData(data)); + delegate.update(data: CodecUtility.encodeMapData(data)); @override Future get({Source source = Source.serverAndCache}) async { @@ -30,10 +31,11 @@ class DocumentReferenceWeb extends DocumentReference { Stream snapshots({bool includeMetadataChanges = false}) => delegate.onSnapshot.map(_fromWeb); + /// Builds [DocumentSnapshot] instance form web snapshot instance DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - _CodecUtility.decodeMapData(webSnapshot.data()), + CodecUtility.decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index f22b6cd3fca2..cbf80236e428 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -31,7 +31,7 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, - _CodecUtility.encodeMapData(data)); + CodecUtility.encodeMapData(data)); } @override @@ -40,13 +40,13 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, - data: _CodecUtility.encodeMapData(data)); + data: CodecUtility.encodeMapData(data)); } DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => DocumentSnapshot( webSnapshot.ref.path, - _CodecUtility.decodeMapData(webSnapshot.data()), + CodecUtility.decodeMapData(webSnapshot.data()), SnapshotMetadata( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 8ac4490843c4..28ffea432d79 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -1,6 +1,7 @@ part of cloud_firestore_web; -class _CodecUtility { +@visibleForTesting +class CodecUtility { static Map encodeMapData(Map data) { if (data == null) { return null; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index f73eae267582..4874a81e853c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -22,7 +22,7 @@ class WriteBatchWeb implements WriteBatch { assert(document is DocumentReferenceWeb); _delegate.set( (document as DocumentReferenceWeb).delegate, - _CodecUtility.encodeMapData(data), + CodecUtility.encodeMapData(data), merge ? web.SetOptions(merge: merge) : null); } @@ -30,6 +30,6 @@ class WriteBatchWeb implements WriteBatch { void updateData(DocumentReference document, Map data) { assert(document is DocumentReferenceWeb); _delegate.set((document as DocumentReferenceWeb).delegate, - _CodecUtility.encodeMapData(data)); + CodecUtility.encodeMapData(data)); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index 80ab8cc5069f..e4da0ec47570 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -3,42 +3,18 @@ import 'dart:js' as js; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; -import 'package:firebase_core_web/firebase_core_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; - -const _kCollectionId = "test"; - -class MockFirestoreWeb extends Mock implements web.Firestore {} - -class MockDocumentReference extends Mock implements web.DocumentReference {} - -class MockQueryWeb extends Mock implements QueryWeb {} - -class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} +import 'test_common.dart'; void main() { group("$CollectionReferenceWeb()", () { - final mockFirestoreWeb = MockFirestoreWeb(); final mockDocumentReference = MockDocumentReference(); CollectionReferenceWeb collectionReference; setUp(() { - final js.JsObject firebaseMock = js.JsObject.jsify({ - 'firestore': js.allowInterop((_) => mockFirestoreWeb), - 'app': js.allowInterop((String name) { - return js.JsObject.jsify({ - 'name': name, - 'options': {'appId': '123'}, - }); - }) - }); - js.context['firebase'] = firebaseMock; - FirebaseCorePlatform.instance = FirebaseCoreWeb(); - FirestorePlatform.instance = FirestoreWeb(); + final mockFirestoreWeb = mockFirestore(); collectionReference = CollectionReferenceWeb(FirestorePlatform.instance, - js.context['firebase']['firestore'](""), [_kCollectionId]); + js.context['firebase']['firestore'](""), [kCollectionId]); collectionReference.queryDelegate = MockQueryWeb(); when(mockFirestoreWeb.doc(any)).thenReturn(mockDocumentReference); when(collectionReference.queryDelegate.resetQueryDelegate()) @@ -51,7 +27,7 @@ void main() { CollectionReferenceWeb( FirestorePlatform.instance, js.context['firebase']['firestore'](""), - [_kCollectionId, _kCollectionId, _kCollectionId]).parent(), + [kCollectionId, kCollectionId, kCollectionId]).parent(), isInstanceOf()); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart new file mode 100644 index 000000000000..c6d2baa05fd7 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -0,0 +1,71 @@ +@TestOn('chrome') +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; +import 'test_common.dart'; + +const _kPath = "test/document"; + +class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} + +class MockWebSnapshotMetaData extends Mock implements web.SnapshotMetadata {} + +void main() { + group("$DocumentReferenceWeb()", () { + final mockWebDocumentReferences = MockDocumentReference(); + DocumentReferenceWeb documentRefernce; + setUp(() { + final mockWebFirestore = mockFirestore(); + when(mockWebFirestore.doc(any)).thenReturn(mockWebDocumentReferences); + documentRefernce = DocumentReferenceWeb( + mockWebFirestore, FirestorePlatform.instance, _kPath.split("/")); + }); + + test("setData", () { + documentRefernce.setData({"test": "test"}); + expect( + verify(mockWebDocumentReferences.set( + any, captureThat(isInstanceOf()))) + .captured + .last + .merge, + isFalse); + documentRefernce.setData({"test": "test"}, merge: true); + expect( + verify(mockWebDocumentReferences.set( + any, captureThat(isInstanceOf()))) + .captured + .last + .merge, + isTrue); + }); + + test("updateData", () { + documentRefernce.updateData({"test": "test"}); + verify(mockWebDocumentReferences.update(data: anyNamed("data"))); + }); + + test("get", () { + final mockWebSnapshot = MockWebDocumentSnapshot(); + when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReferences); + when(mockWebSnapshot.metadata).thenReturn(MockWebSnapshotMetaData()); + when(mockWebDocumentReferences.get()) + .thenAnswer((_) => Future.value(mockWebSnapshot)); + documentRefernce.get(); + verify(mockWebDocumentReferences.get()); + }); + + test("delete", () { + documentRefernce.delete(); + verify(mockWebDocumentReferences.delete()); + }); + + test("snapshots", () { + when(mockWebDocumentReferences.onSnapshot).thenReturn(Stream.empty()); + documentRefernce.snapshots(); + verify(mockWebDocumentReferences.onSnapshot); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart new file mode 100644 index 000000000000..8dca6a555482 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -0,0 +1,34 @@ +import 'dart:js' as js; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:firebase_core_web/firebase_core_web.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; + +const kCollectionId = "test"; + +class MockFirestoreWeb extends Mock implements web.Firestore {} + +class MockDocumentReference extends Mock implements web.DocumentReference {} + +class MockQueryWeb extends Mock implements QueryWeb {} + +class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} + +web.Firestore mockFirestore() { + final mockFirestoreWeb = MockFirestoreWeb(); + final js.JsObject firebaseMock = js.JsObject.jsify({ + 'firestore': js.allowInterop((_) => mockFirestoreWeb), + 'app': js.allowInterop((String name) { + return js.JsObject.jsify({ + 'name': name, + 'options': {'appId': '123'}, + }); + }) + }); + js.context['firebase'] = firebaseMock; + FirebaseCorePlatform.instance = FirebaseCoreWeb(); + FirestorePlatform.instance = FirestoreWeb(); + return mockFirestoreWeb; +} From 4b79e2626590d158fc33484fa1bddd91a1bd203b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 17:26:56 +0000 Subject: [PATCH 081/144] Fix typo --- .../lib/src/method_channel_document_change.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart index 477e10d7c014..9f92fc24bd1e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart @@ -20,7 +20,7 @@ class MethodChannelDocumentChange extends DocumentChange { DocumentSnapshot( data['path'], _asStringKeyedMap(data['document']), - SnapshotMetadata(data['etadata']['hasPendingWrites'], + SnapshotMetadata(data['metadata']['hasPendingWrites'], data['metadata']['isFromCache']), firestore, )); From 5391128c129bb6796ca7e1edce4d17916b12fbef Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 18:03:02 +0000 Subject: [PATCH 082/144] Fix analyze issues --- .../lib/cloud_firestore_platform_interface.dart | 15 +++++++++++++++ .../lib/src/geo_point.dart | 4 ++-- .../document_reference_interface.dart | 1 + 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index ca060d6176a0..59da30606852 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -41,19 +41,26 @@ part 'src/transaction_platform_interface.dart'; part 'src/write_batch.dart'; part 'src/write_batch_platform_interface.dart'; +/// Defines an interface to work with [FirestorePlatform] on web and mobile abstract class FirestorePlatform extends PlatformInterface { + /// [FirebaseApp] used for this firestore instance final FirebaseApp app; + /// Create an instance using [app] FirestorePlatform({FirebaseApp app}) : app = app ?? FirebaseApp.instance, super(token: _token); static final Object _token = Object(); + /// Create an instance using [app] using the existing implementation factory FirestorePlatform.withApp({FirebaseApp app}) { return FirestorePlatform.instance.withApp(app); } + /// return the current default [FirestorePlatform] instance + /// It will always default to [MethodChannelFirestore] + /// if no web implementation was provided static FirestorePlatform get instance { if (_instance == null) { _instance = MethodChannelFirestore(); @@ -63,15 +70,18 @@ abstract class FirestorePlatform extends PlatformInterface { static FirestorePlatform _instance; + /// Sets the [FirestorePlatform.instance] static set instance(FirestorePlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; } + /// Create a new [FirestorePlatform] with a [FirebaseApp] instance FirestorePlatform withApp(FirebaseApp app) { throw UnimplementedError("withApp() not implemented"); } + /// Firebase app name String appName() { throw UnimplementedError("appName() not implemented"); } @@ -128,10 +138,15 @@ abstract class FirestorePlatform extends PlatformInterface { } @deprecated + // Suppressing due to deprecation + // ignore: public_member_api_docs Future enablePersistence(bool enable) async { throw UnimplementedError('enablePersistence() is not implemented'); } + /// Setup [FirestorePlatform] with settings. + /// if [sslEnabled] has value the [host] must have non-null value as well + /// if [cacheSizeBytes] is null then default values are used. Future settings( {bool persistenceEnabled, String host, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart index c54f7e5cb462..cae3227690df 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -9,8 +9,8 @@ class GeoPoint { /// Create [GeoPoint] instance const GeoPoint(this.latitude, this.longitude); - final double latitude; - final double longitude; + final double latitude; // ignore: public_member_api_docs + final double longitude; // ignore: public_member_api_docs @override bool operator ==(dynamic o) => diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart index 5960e27aea31..558d42544e11 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart @@ -7,6 +7,7 @@ part of cloud_firestore_platform_interface; /// A [DocumentReference] can also be used to create a [CollectionReference] /// to a subcollection. abstract class DocumentReference { + /// Create instance of [DocumentReference] DocumentReference(this.firestore, this._pathComponents); /// The Firestore instance associated with this document reference From d3e60d5373f0850d93f46bfd387cc603b7e79f33 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 21 Dec 2019 22:42:22 +0000 Subject: [PATCH 083/144] Added firestore_web codec_utility_test --- .../test/codec_utility_test.dart | 162 ++++++++++++++++++ .../test/document_reference_web_test.dart | 2 +- 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart new file mode 100644 index 000000000000..7588f9e0a302 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -0,0 +1,162 @@ +import 'dart:typed_data'; + +@TestOn("chrome") +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'dart:js' as js; +import 'package:firebase/firestore.dart' as web; + +class MockFieldValueInterface extends Mock implements FieldValueInterface {} + +class MockGeoPoint extends Mock implements GeoPoint {} + +class MockBlob extends Mock implements Blob {} + +class MockDocumentReferenceWeb extends Mock implements DocumentReferenceWeb {} + +class MockWebGeoPoint extends Mock implements web.GeoPoint {} + +class MockWebBlob extends Mock implements web.Blob {} + +void main() { + group("$CodecUtility()", () { + setUp(() { + js.context['firebase'] = js.JsObject.jsify({ + 'firestore': js.JsObject.jsify({ + 'GeoPoint': + js.allowInterop((latitude, longitude) => MockWebGeoPoint()), + 'Blob': js.JsObject.jsify({ + 'fromUint8Array': js.allowInterop((_) => MockWebBlob()) + }) + }) + }); + }); + test("encodeMapData", () { + expect(CodecUtility.encodeMapData(null), isNull); + + //FieldValueInterface + final mockFieldValueInterface = MockFieldValueInterface(); + CodecUtility.encodeMapData({'test': mockFieldValueInterface}); + verify(mockFieldValueInterface.instance); + + //GeoPoint + final mockGeoPoint = MockGeoPoint(); + CodecUtility.encodeMapData({'test': mockGeoPoint}); + verify(mockGeoPoint.latitude); + verify(mockGeoPoint.longitude); + + //Blob + final mockBlob = MockBlob(); + CodecUtility.encodeMapData({'test': mockBlob}); + verify(mockBlob.bytes); + + //DocumentReferenceWeb + final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); + CodecUtility.encodeMapData({'test': mockDocumentReferenceWeb}); + verify(mockDocumentReferenceWeb.delegate); + + //Map + reset(mockDocumentReferenceWeb); + CodecUtility.encodeMapData({ + 'test': {'test2': mockDocumentReferenceWeb} + }); + verify(mockDocumentReferenceWeb.delegate); + + //List + reset(mockDocumentReferenceWeb); + CodecUtility.encodeMapData({ + 'test': [mockDocumentReferenceWeb] + }); + verify(mockDocumentReferenceWeb.delegate); + }); + + test("encodeArrayData", () { + expect(CodecUtility.encodeArrayData(null), isNull); + + //FieldValueInterface + final mockFieldValueInterface = MockFieldValueInterface(); + CodecUtility.encodeArrayData([mockFieldValueInterface]); + verify(mockFieldValueInterface.instance); + + //GeoPoint + final mockGeoPoint = MockGeoPoint(); + CodecUtility.encodeArrayData([mockGeoPoint]); + verify(mockGeoPoint.latitude); + verify(mockGeoPoint.longitude); + + //Blob + final mockBlob = MockBlob(); + CodecUtility.encodeArrayData([mockBlob]); + verify(mockBlob.bytes); + + //DocumentReferenceWeb + final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); + CodecUtility.encodeArrayData([mockDocumentReferenceWeb]); + verify(mockDocumentReferenceWeb.delegate); + + //Map + reset(mockDocumentReferenceWeb); + CodecUtility.encodeArrayData([ + {'test2': mockDocumentReferenceWeb} + ]); + verify(mockDocumentReferenceWeb.delegate); + + //List + reset(mockDocumentReferenceWeb); + CodecUtility.encodeArrayData([ + [mockDocumentReferenceWeb] + ]); + verify(mockDocumentReferenceWeb.delegate); + }); + + test("decodeMapData", () { + expect(CodecUtility.decodeMapData(null), isNull); + + //Blob + final mockWebBlob = MockWebBlob(); + when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); + expect(CodecUtility.decodeMapData({'test': mockWebBlob})['test'], + isInstanceOf()); + verify(mockWebBlob.toUint8Array()); + + //GeoPoint + final mockWebGeoPoint = MockWebGeoPoint(); + expect(CodecUtility.decodeMapData({'test': mockWebGeoPoint})['test'], + isInstanceOf()); + + //Map + expect(CodecUtility.decodeMapData({'test':{'test1': mockWebGeoPoint}})['test']['test1'], + isInstanceOf()); + + //List + expect(CodecUtility.decodeMapData({'test':[mockWebGeoPoint]})['test'].first, + isInstanceOf()); + }); + + test("decodeArrayData", () { + expect(CodecUtility.decodeArrayData(null), isNull); + + //Blob + final mockWebBlob = MockWebBlob(); + when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); + expect(CodecUtility.decodeArrayData([mockWebBlob]).first, + isInstanceOf()); + verify(mockWebBlob.toUint8Array()); + + //GeoPoint + final mockWebGeoPoint = MockWebGeoPoint(); + expect(CodecUtility.decodeArrayData([mockWebGeoPoint]).first, + isInstanceOf()); + + //Map + expect(CodecUtility.decodeArrayData([{'test1': mockWebGeoPoint}]).first['test1'], + isInstanceOf()); + + //List + expect(CodecUtility.decodeArrayData([[mockWebGeoPoint]]).first.first, + isInstanceOf()); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart index c6d2baa05fd7..4684bd36edfc 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -63,7 +63,7 @@ void main() { }); test("snapshots", () { - when(mockWebDocumentReferences.onSnapshot).thenReturn(Stream.empty()); + when(mockWebDocumentReferences.onSnapshot).thenAnswer((_) => Stream.empty()); documentRefernce.snapshots(); verify(mockWebDocumentReferences.onSnapshot); }); From cac92e2d0c3e424c3b504c4c72d5f6548bfbd92e Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 10:47:33 +0000 Subject: [PATCH 084/144] Added test for field factory web --- .../lib/field_value_factory_web.dart | 4 +- .../test/field_value_factory_web_test.dart | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 0cd65b7e1a93..609c6045d847 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -25,8 +25,8 @@ class FieldValueFactoryWeb implements FieldValueFactory { final delegate = web.FieldValue.increment(value); return FieldValueWeb._( delegate, - value is double - ? FieldValueType.incrementDouble + value is int + ? FieldValueType.incrementInteger : FieldValueType.incrementDouble, value); } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart new file mode 100644 index 000000000000..8401f4f61ffa --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -0,0 +1,44 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group("$FieldValueFactoryWeb()", (){ + final factory = FieldValueFactoryWeb(); + + test("arrayRemove", (){ + final actual = factory.arrayRemove([]); + expect(actual, isInstanceOf()); + expect(actual.type, equals(FieldValueType.arrayRemove)); + }); + + test("arrayUnion", (){ + final actual = factory.arrayUnion([]); + expect(actual, isInstanceOf()); + expect(actual.type, equals(FieldValueType.arrayUnion)); + }); + + test("delete", (){ + final actual = factory.delete(); + expect(actual, isInstanceOf()); + expect(actual.type, equals(FieldValueType.delete)); + }); + + test("increment", (){ + final actualInt = factory.increment(1); + expect(actualInt, isInstanceOf()); + expect(actualInt.type, equals(FieldValueType.incrementInteger)); + + final actualDouble = factory.increment(1.25); + expect(actualDouble, isInstanceOf()); + expect(actualDouble.type, equals(FieldValueType.incrementDouble)); + }); + + test("serverTimestamp", (){ + final actual = factory.serverTimestamp(); + expect(actual, isInstanceOf()); + expect(actual.type, equals(FieldValueType.serverTimestamp)); + }); + + }); +} \ No newline at end of file From 207cc23d9fb9b31b05b8848fb13fade78f14c82f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 17:00:38 +0000 Subject: [PATCH 085/144] unit tested get document for QueryWeb --- .../cloud_firestore_web/lib/query_web.dart | 53 +++++++------ .../test/query_web_test.dart | 77 +++++++++++++++++++ 2 files changed, 107 insertions(+), 23 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index b360c9b29cbc..40c46388a402 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,7 +1,8 @@ part of cloud_firestore_web; +/// Web implementation for firestore [Query] class QueryWeb implements Query { - final web.Query webQuery; + final web.Query _webQuery; final FirestorePlatform _firestore; final bool _isCollectionGroup; final String _path; @@ -10,22 +11,28 @@ class QueryWeb implements Query { static const _kChangeTypeModified = "modified"; static const _kChangeTypeRemoved = "removed"; - QueryWeb(this._firestore, this._path, this.webQuery, + /// Builds an instance of [QueryWeb] using [_path] & [_webQuery] + /// to delegate queries to underlying firestore web plugin + QueryWeb(this._firestore, this._path, this._webQuery, {bool isCollectionGroup, List orderByKeys}) : this._isCollectionGroup = isCollectionGroup ?? false, this._orderByKeys = orderByKeys ?? []; @override Stream snapshots({bool includeMetadataChanges = false}) { - assert(webQuery != null); - return webQuery.onSnapshot.map(_webQuerySnapshotToQuerySnapshot); + assert(_webQuery != null); + Stream querySnapshots = _webQuery.onSnapshot; + if(includeMetadataChanges){ + querySnapshots = _webQuery.onSnapshotMetadata; + } + return querySnapshots.map(_webQuerySnapshotToQuerySnapshot); } @override Future getDocuments( {Source source = Source.serverAndCache}) async { - assert(webQuery != null); - return _webQuerySnapshotToQuerySnapshot(await webQuery.get()); + assert(_webQuery != null); + return _webQuerySnapshotToQuerySnapshot(await _webQuery.get()); } @override @@ -33,16 +40,16 @@ class QueryWeb implements Query { @override Query endAt(List values) => QueryWeb(this._firestore, this._path, - webQuery != null ? webQuery.endAt(fieldValues: values) : null, + _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); @override Query endAtDocument(DocumentSnapshot documentSnapshot) { - assert(webQuery != null && _orderByKeys.isNotEmpty); + assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, this._path, - webQuery.endAt( + _webQuery.endAt( fieldValues: _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), isCollectionGroup: _isCollectionGroup); @@ -50,16 +57,16 @@ class QueryWeb implements Query { @override Query endBefore(List values) => QueryWeb(this._firestore, this._path, - webQuery != null ? webQuery.endBefore(fieldValues: values) : null, + _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); @override Query endBeforeDocument(DocumentSnapshot documentSnapshot) { - assert(webQuery != null && _orderByKeys.isNotEmpty); + assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, this._path, - webQuery.endBefore( + _webQuery.endBefore( fieldValues: _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), isCollectionGroup: _isCollectionGroup); @@ -75,7 +82,7 @@ class QueryWeb implements Query { Query limit(int length) => QueryWeb( this._firestore, this._path, - webQuery != null ? webQuery.limit(length) : null, + _webQuery != null ? _webQuery.limit(length) : null, orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup, ); @@ -89,7 +96,7 @@ class QueryWeb implements Query { return QueryWeb( this._firestore, this._path, - webQuery.orderBy(usableField, descending ? "desc" : "asc"), + _webQuery.orderBy(usableField, descending ? "desc" : "asc"), orderByKeys: _orderByKeys..add(usableField), isCollectionGroup: _isCollectionGroup, ); @@ -106,16 +113,16 @@ class QueryWeb implements Query { @override Query startAfter(List values) => QueryWeb( - this._firestore, this._path, webQuery.startAfter(fieldValues: values), + this._firestore, this._path, _webQuery.startAfter(fieldValues: values), orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); @override Query startAfterDocument(DocumentSnapshot documentSnapshot) { - assert(webQuery != null && _orderByKeys.isNotEmpty); + assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, this._path, - webQuery.startAfter( + _webQuery.startAfter( fieldValues: _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), orderByKeys: _orderByKeys, @@ -126,18 +133,18 @@ class QueryWeb implements Query { Query startAt(List values) => QueryWeb( this._firestore, this._path, - webQuery.startAt(fieldValues: values), + _webQuery.startAt(fieldValues: values), orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup, ); @override Query startAtDocument(DocumentSnapshot documentSnapshot) { - assert(webQuery != null && _orderByKeys.isNotEmpty); + assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, this._path, - webQuery.startAt( + _webQuery.startAt( fieldValues: _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), orderByKeys: _orderByKeys, @@ -157,12 +164,12 @@ class QueryWeb implements Query { bool isNull}) { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); - assert(webQuery != null); + assert(_webQuery != null); dynamic usableField = field; if (field == FieldPath.documentId) { usableField = web.FieldPath.documentId(); } - web.Query query = webQuery; + web.Query query = _webQuery; if (isEqualTo != null) { query = query.where(usableField, "==", isEqualTo); @@ -252,5 +259,5 @@ class QueryWeb implements Query { @visibleForTesting QueryWeb resetQueryDelegate() => - QueryWeb(firestore, pathComponents.join("/"), webQuery); + QueryWeb(firestore, pathComponents.join("/"), _webQuery); } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart new file mode 100644 index 000000000000..f735f4a6df02 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -0,0 +1,77 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; +import 'document_reference_web_test.dart'; +import 'test_common.dart'; + +class MockWebQuery extends Mock implements web.Query {} +class MockFirestoreWeb extends Mock implements FirestoreWeb {} +class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} +class MockWebSnapshotMetadata extends Mock implements web.SnapshotMetadata {} +class MockWebDocumentChange extends Mock implements web.DocumentChange {} + +const _path = "test/query"; + +void main() { + group("$QueryWeb()", (){ + final firestore = MockFirestoreWeb(); + final MockWebQuery mockWebQuery = MockWebQuery(); + QueryWeb query; + + setUp((){ + reset(mockWebQuery); + query = QueryWeb(firestore, _path, mockWebQuery); + }); + + test("snapshots", (){ + when(mockWebQuery.onSnapshot).thenAnswer((_) => Stream.empty()); + when(mockWebQuery.onSnapshotMetadata).thenAnswer((_) => Stream.empty()); + query.snapshots(); + verify(mockWebQuery.onSnapshot); + query.snapshots(includeMetadataChanges: false); + verify(mockWebQuery.onSnapshot); + query.snapshots(includeMetadataChanges: true); + verify(mockWebQuery.onSnapshotMetadata); + }); + + test("getDocuments", () async { + + final mockMetaData = MockWebSnapshotMetadata(); + when(mockMetaData.fromCache).thenReturn(true); + when(mockMetaData.hasPendingWrites).thenReturn(false); + + final mockDocumentReference = MockDocumentReference(); + when(mockDocumentReference.path).thenReturn("test/reference"); + + final mockDocumentSnapshot = MockWebDocumentSnapshot(); + when(mockDocumentSnapshot.ref).thenReturn(mockDocumentReference); + when(mockDocumentSnapshot.data()).thenReturn(Map()); + when(mockDocumentSnapshot.metadata).thenReturn(mockMetaData); + + final mockDocumentChange = MockWebDocumentChange(); + when(mockDocumentChange.type).thenReturn("added"); + when(mockDocumentChange.oldIndex).thenReturn(0); + when(mockDocumentChange.newIndex).thenReturn(1); + when(mockDocumentChange.doc).thenReturn(mockDocumentSnapshot); + + final mockQuerySnapshot = MockWebQuerySnapshot(); + when(mockQuerySnapshot.docs).thenReturn([]); + when(mockQuerySnapshot.docChanges()).thenReturn([mockDocumentChange]); + when(mockQuerySnapshot.metadata).thenReturn(mockMetaData); + + when(mockWebQuery.get()).thenAnswer((_) => Future.value(mockQuerySnapshot)); + final actual = await query.getDocuments(); + verify(mockWebQuery.get()); + expect(actual.documentChanges.first.type, equals(DocumentChangeType.added)); + + + when(mockDocumentChange.type).thenReturn("modified"); + expect((await query.getDocuments()).documentChanges.first.type, equals(DocumentChangeType.modified)); + + when(mockDocumentChange.type).thenReturn("removed"); + expect((await query.getDocuments()).documentChanges.first.type, equals(DocumentChangeType.removed)); + }); + }); +} \ No newline at end of file From 5accb7ae8818179267eab5edba5943af0bf86e63 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 17:25:05 +0000 Subject: [PATCH 086/144] Added more unit tests for QueryWeb --- .../test/query_web_test.dart | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index f735f4a6df02..529f137c67d0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -1,3 +1,4 @@ +@TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -73,5 +74,99 @@ void main() { when(mockDocumentChange.type).thenReturn("removed"); expect((await query.getDocuments()).documentChanges.first.type, equals(DocumentChangeType.removed)); }); + + test("endAt", (){ + query.endAt([]); + verify(mockWebQuery.endAt(fieldValues: anyNamed("fieldValues"))); + }); + + test("endAtDocument", (){ + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test':1, + }); + query.orderBy("test"); + query.endAtDocument(mockDocumentSnapshot); + verify(mockWebQuery.endAt(fieldValues: argThat(equals([1]),named: "fieldValues"))); + }); + + test("endBefore", (){ + query.endBefore([]); + verify(mockWebQuery.endBefore(fieldValues: anyNamed("fieldValues"))); + }); + + test("endBeforeDocument", (){ + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test':1, + }); + query.orderBy("test"); + query.endBeforeDocument(mockDocumentSnapshot); + verify(mockWebQuery.endBefore(fieldValues: argThat(equals([1]),named: "fieldValues"))); + }); + + test("startAfter", (){ + query.startAfter([]); + verify(mockWebQuery.startAfter(fieldValues: anyNamed("fieldValues"))); + }); + + test("startAfterDocument", (){ + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test':1, + }); + query.orderBy("test"); + query.startAfterDocument(mockDocumentSnapshot); + verify(mockWebQuery.startAfter(fieldValues: argThat(equals([1]),named: "fieldValues"))); + }); + + test("startAt", (){ + query.startAt([]); + verify(mockWebQuery.startAt(fieldValues: anyNamed("fieldValues"))); + }); + + test("startAtDocument", (){ + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test':1, + }); + query.orderBy("test"); + query.startAtDocument(mockDocumentSnapshot); + verify(mockWebQuery.startAt(fieldValues: argThat(equals([1]),named: "fieldValues"))); + }); + + test("limit", (){ + query.limit(1); + verify(mockWebQuery.limit(1)); + }); + + test("where",(){ + query.where("test",isNull: true); + verify(mockWebQuery.where("test", "==", null)); + + query.where("test", whereIn: [1,2,3]); + verify(mockWebQuery.where("test", "in" , [1,2,3])); + + query.where("test", arrayContainsAny: [1,2,3]); + verify(mockWebQuery.where("test", "array-contains-any" , [1,2,3])); + + query.where("test", arrayContains: [1,2,3]); + verify(mockWebQuery.where("test", "array-contains" , [1,2,3])); + + query.where("test",isGreaterThanOrEqualTo: 1); + verify(mockWebQuery.where("test", ">=" , 1)); + + query.where("test",isGreaterThan: 1); + verify(mockWebQuery.where("test", ">" , 1)); + + query.where("test",isLessThan: 1); + verify(mockWebQuery.where("test", "<" , 1)); + + query.where("test",isLessThanOrEqualTo: 1); + verify(mockWebQuery.where("test", "<=" , 1)); + + query.where("test",isEqualTo: 1); + verify(mockWebQuery.where("test", "==" , 1)); + }); }); } \ No newline at end of file From ac1907dc2d0e1d3082328e84bdc398f13eb4dcc7 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 17:34:27 +0000 Subject: [PATCH 087/144] Formatted code --- .../lib/document_reference_web.dart | 9 +- .../cloud_firestore_web/lib/query_web.dart | 2 +- .../test/codec_utility_test.dart | 21 +++- .../test/document_reference_web_test.dart | 11 +- .../test/field_value_factory_web_test.dart | 15 ++- .../test/query_web_test.dart | 104 ++++++++++-------- 6 files changed, 99 insertions(+), 63 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index d8f3638f9d6b..94730824533a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -28,8 +28,13 @@ class DocumentReferenceWeb extends DocumentReference { Future delete() => delegate.delete(); @override - Stream snapshots({bool includeMetadataChanges = false}) => - delegate.onSnapshot.map(_fromWeb); + Stream snapshots({bool includeMetadataChanges = false}) { + Stream querySnapshots = delegate.onSnapshot; + if (includeMetadataChanges) { + querySnapshots = delegate.onMetadataChangesSnapshot; + } + return querySnapshots.map(_fromWeb); + } /// Builds [DocumentSnapshot] instance form web snapshot instance DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 40c46388a402..3eae61dc9d7c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -22,7 +22,7 @@ class QueryWeb implements Query { Stream snapshots({bool includeMetadataChanges = false}) { assert(_webQuery != null); Stream querySnapshots = _webQuery.onSnapshot; - if(includeMetadataChanges){ + if (includeMetadataChanges) { querySnapshots = _webQuery.onSnapshotMetadata; } return querySnapshots.map(_webQuerySnapshotToQuerySnapshot); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index 7588f9e0a302..7fcecee03aa8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -127,11 +127,18 @@ void main() { isInstanceOf()); //Map - expect(CodecUtility.decodeMapData({'test':{'test1': mockWebGeoPoint}})['test']['test1'], + expect( + CodecUtility.decodeMapData({ + 'test': {'test1': mockWebGeoPoint} + })['test']['test1'], isInstanceOf()); //List - expect(CodecUtility.decodeMapData({'test':[mockWebGeoPoint]})['test'].first, + expect( + CodecUtility.decodeMapData({ + 'test': [mockWebGeoPoint] + })['test'] + .first, isInstanceOf()); }); @@ -151,11 +158,17 @@ void main() { isInstanceOf()); //Map - expect(CodecUtility.decodeArrayData([{'test1': mockWebGeoPoint}]).first['test1'], + expect( + CodecUtility.decodeArrayData([ + {'test1': mockWebGeoPoint} + ]).first['test1'], isInstanceOf()); //List - expect(CodecUtility.decodeArrayData([[mockWebGeoPoint]]).first.first, + expect( + CodecUtility.decodeArrayData([ + [mockWebGeoPoint] + ]).first.first, isInstanceOf()); }); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart index 4684bd36edfc..1d3039988ea7 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -1,3 +1,5 @@ +import 'dart:html'; + @TestOn('chrome') import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; @@ -63,9 +65,16 @@ void main() { }); test("snapshots", () { - when(mockWebDocumentReferences.onSnapshot).thenAnswer((_) => Stream.empty()); + when(mockWebDocumentReferences.onSnapshot) + .thenAnswer((_) => Stream.empty()); + when(mockWebDocumentReferences.onMetadataChangesSnapshot) + .thenAnswer((_) => Stream.empty()); documentRefernce.snapshots(); verify(mockWebDocumentReferences.onSnapshot); + documentRefernce.snapshots(includeMetadataChanges: false); + verify(mockWebDocumentReferences.onSnapshot); + documentRefernce.snapshots(includeMetadataChanges: true); + verify(mockWebDocumentReferences.onMetadataChangesSnapshot); }); }); } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart index 8401f4f61ffa..4b114153caac 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -3,28 +3,28 @@ import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { - group("$FieldValueFactoryWeb()", (){ + group("$FieldValueFactoryWeb()", () { final factory = FieldValueFactoryWeb(); - test("arrayRemove", (){ + test("arrayRemove", () { final actual = factory.arrayRemove([]); expect(actual, isInstanceOf()); expect(actual.type, equals(FieldValueType.arrayRemove)); }); - test("arrayUnion", (){ + test("arrayUnion", () { final actual = factory.arrayUnion([]); expect(actual, isInstanceOf()); expect(actual.type, equals(FieldValueType.arrayUnion)); }); - test("delete", (){ + test("delete", () { final actual = factory.delete(); expect(actual, isInstanceOf()); expect(actual.type, equals(FieldValueType.delete)); }); - test("increment", (){ + test("increment", () { final actualInt = factory.increment(1); expect(actualInt, isInstanceOf()); expect(actualInt.type, equals(FieldValueType.incrementInteger)); @@ -34,11 +34,10 @@ void main() { expect(actualDouble.type, equals(FieldValueType.incrementDouble)); }); - test("serverTimestamp", (){ + test("serverTimestamp", () { final actual = factory.serverTimestamp(); expect(actual, isInstanceOf()); expect(actual.type, equals(FieldValueType.serverTimestamp)); }); - }); -} \ No newline at end of file +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index 529f137c67d0..b423cb4d2f48 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -8,25 +8,29 @@ import 'document_reference_web_test.dart'; import 'test_common.dart'; class MockWebQuery extends Mock implements web.Query {} + class MockFirestoreWeb extends Mock implements FirestoreWeb {} + class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} + class MockWebSnapshotMetadata extends Mock implements web.SnapshotMetadata {} + class MockWebDocumentChange extends Mock implements web.DocumentChange {} const _path = "test/query"; void main() { - group("$QueryWeb()", (){ + group("$QueryWeb()", () { final firestore = MockFirestoreWeb(); final MockWebQuery mockWebQuery = MockWebQuery(); QueryWeb query; - setUp((){ + setUp(() { reset(mockWebQuery); query = QueryWeb(firestore, _path, mockWebQuery); }); - test("snapshots", (){ + test("snapshots", () { when(mockWebQuery.onSnapshot).thenAnswer((_) => Stream.empty()); when(mockWebQuery.onSnapshotMetadata).thenAnswer((_) => Stream.empty()); query.snapshots(); @@ -38,7 +42,6 @@ void main() { }); test("getDocuments", () async { - final mockMetaData = MockWebSnapshotMetadata(); when(mockMetaData.fromCache).thenReturn(true); when(mockMetaData.hasPendingWrites).thenReturn(false); @@ -48,7 +51,7 @@ void main() { final mockDocumentSnapshot = MockWebDocumentSnapshot(); when(mockDocumentSnapshot.ref).thenReturn(mockDocumentReference); - when(mockDocumentSnapshot.data()).thenReturn(Map()); + when(mockDocumentSnapshot.data()).thenReturn(Map()); when(mockDocumentSnapshot.metadata).thenReturn(mockMetaData); final mockDocumentChange = MockWebDocumentChange(); @@ -62,111 +65,118 @@ void main() { when(mockQuerySnapshot.docChanges()).thenReturn([mockDocumentChange]); when(mockQuerySnapshot.metadata).thenReturn(mockMetaData); - when(mockWebQuery.get()).thenAnswer((_) => Future.value(mockQuerySnapshot)); + when(mockWebQuery.get()) + .thenAnswer((_) => Future.value(mockQuerySnapshot)); final actual = await query.getDocuments(); verify(mockWebQuery.get()); - expect(actual.documentChanges.first.type, equals(DocumentChangeType.added)); - + expect( + actual.documentChanges.first.type, equals(DocumentChangeType.added)); when(mockDocumentChange.type).thenReturn("modified"); - expect((await query.getDocuments()).documentChanges.first.type, equals(DocumentChangeType.modified)); + expect((await query.getDocuments()).documentChanges.first.type, + equals(DocumentChangeType.modified)); when(mockDocumentChange.type).thenReturn("removed"); - expect((await query.getDocuments()).documentChanges.first.type, equals(DocumentChangeType.removed)); + expect((await query.getDocuments()).documentChanges.first.type, + equals(DocumentChangeType.removed)); }); - - test("endAt", (){ + + test("endAt", () { query.endAt([]); verify(mockWebQuery.endAt(fieldValues: anyNamed("fieldValues"))); }); - test("endAtDocument", (){ + test("endAtDocument", () { final mockDocumentSnapshot = MockDocumentSnapshot(); when(mockDocumentSnapshot.data).thenReturn({ - 'test':1, + 'test': 1, }); query.orderBy("test"); query.endAtDocument(mockDocumentSnapshot); - verify(mockWebQuery.endAt(fieldValues: argThat(equals([1]),named: "fieldValues"))); + verify(mockWebQuery.endAt( + fieldValues: argThat(equals([1]), named: "fieldValues"))); }); - test("endBefore", (){ + test("endBefore", () { query.endBefore([]); verify(mockWebQuery.endBefore(fieldValues: anyNamed("fieldValues"))); }); - test("endBeforeDocument", (){ + test("endBeforeDocument", () { final mockDocumentSnapshot = MockDocumentSnapshot(); when(mockDocumentSnapshot.data).thenReturn({ - 'test':1, + 'test': 1, }); query.orderBy("test"); query.endBeforeDocument(mockDocumentSnapshot); - verify(mockWebQuery.endBefore(fieldValues: argThat(equals([1]),named: "fieldValues"))); + verify(mockWebQuery.endBefore( + fieldValues: argThat(equals([1]), named: "fieldValues"))); }); - test("startAfter", (){ + test("startAfter", () { query.startAfter([]); verify(mockWebQuery.startAfter(fieldValues: anyNamed("fieldValues"))); }); - test("startAfterDocument", (){ + test("startAfterDocument", () { final mockDocumentSnapshot = MockDocumentSnapshot(); when(mockDocumentSnapshot.data).thenReturn({ - 'test':1, + 'test': 1, }); query.orderBy("test"); query.startAfterDocument(mockDocumentSnapshot); - verify(mockWebQuery.startAfter(fieldValues: argThat(equals([1]),named: "fieldValues"))); + verify(mockWebQuery.startAfter( + fieldValues: argThat(equals([1]), named: "fieldValues"))); }); - test("startAt", (){ + test("startAt", () { query.startAt([]); verify(mockWebQuery.startAt(fieldValues: anyNamed("fieldValues"))); }); - test("startAtDocument", (){ + test("startAtDocument", () { final mockDocumentSnapshot = MockDocumentSnapshot(); when(mockDocumentSnapshot.data).thenReturn({ - 'test':1, + 'test': 1, }); query.orderBy("test"); query.startAtDocument(mockDocumentSnapshot); - verify(mockWebQuery.startAt(fieldValues: argThat(equals([1]),named: "fieldValues"))); + verify(mockWebQuery.startAt( + fieldValues: argThat(equals([1]), named: "fieldValues"))); }); - test("limit", (){ + test("limit", () { query.limit(1); verify(mockWebQuery.limit(1)); }); - test("where",(){ - query.where("test",isNull: true); + test("where", () { + query.where("test", isNull: true); verify(mockWebQuery.where("test", "==", null)); - query.where("test", whereIn: [1,2,3]); - verify(mockWebQuery.where("test", "in" , [1,2,3])); + query.where("test", whereIn: [1, 2, 3]); + verify(mockWebQuery.where("test", "in", [1, 2, 3])); - query.where("test", arrayContainsAny: [1,2,3]); - verify(mockWebQuery.where("test", "array-contains-any" , [1,2,3])); + query.where("test", arrayContainsAny: [1, 2, 3]); + verify(mockWebQuery.where("test", "array-contains-any", [1, 2, 3])); - query.where("test", arrayContains: [1,2,3]); - verify(mockWebQuery.where("test", "array-contains" , [1,2,3])); + query.where("test", arrayContains: [1, 2, 3]); + verify(mockWebQuery.where("test", "array-contains", [1, 2, 3])); - query.where("test",isGreaterThanOrEqualTo: 1); - verify(mockWebQuery.where("test", ">=" , 1)); + query.where("test", isGreaterThanOrEqualTo: 1); + verify(mockWebQuery.where("test", ">=", 1)); - query.where("test",isGreaterThan: 1); - verify(mockWebQuery.where("test", ">" , 1)); + query.where("test", isGreaterThan: 1); + verify(mockWebQuery.where("test", ">", 1)); - query.where("test",isLessThan: 1); - verify(mockWebQuery.where("test", "<" , 1)); + query.where("test", isLessThan: 1); + verify(mockWebQuery.where("test", "<", 1)); - query.where("test",isLessThanOrEqualTo: 1); - verify(mockWebQuery.where("test", "<=" , 1)); + query.where("test", isLessThanOrEqualTo: 1); + verify(mockWebQuery.where("test", "<=", 1)); - query.where("test",isEqualTo: 1); - verify(mockWebQuery.where("test", "==" , 1)); + query.where("test", isEqualTo: 1); + verify(mockWebQuery.where("test", "==", 1)); }); }); -} \ No newline at end of file +} From 7c2ff0599490bd6ace8d87c808c9ca5203baff71 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 17:48:56 +0000 Subject: [PATCH 088/144] Added public methods documentation --- .../cloud_firestore_web/lib/collection_reference_web.dart | 6 +++++- .../cloud_firestore_web/lib/document_reference_web.dart | 5 +++++ .../cloud_firestore_web/lib/field_value_factory_web.dart | 2 ++ .../cloud_firestore_web/lib/field_value_web.dart | 2 ++ .../cloud_firestore_web/lib/firestore_web.dart | 7 +++++++ .../cloud_firestore/cloud_firestore_web/lib/query_web.dart | 2 ++ .../cloud_firestore_web/lib/transaction_web.dart | 1 + .../cloud_firestore_web/lib/utils/codec_utility.dart | 2 ++ .../cloud_firestore_web/lib/write_batch_web.dart | 1 + 9 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 6a1a78c3d95c..19560e77373d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -2,12 +2,16 @@ part of cloud_firestore_web; /// Web implementation for Firestore [CollectionReference] class CollectionReferenceWeb implements CollectionReference { + /// instance of Firestore from the web plugin final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; final List pathComponents; + // disabling lint as it's only visible for testing @visibleForTesting - QueryWeb queryDelegate; + QueryWeb queryDelegate; // ignore: public_member_api_docs + /// Creates an instance of [CollectionReferenceWeb] which represents path + /// at [pathComponents] and uses implementation of [webFirestore] CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 94730824533a..66acc7854fe8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -2,9 +2,14 @@ part of cloud_firestore_web; /// Web implementation for firestore [DocumentReference] class DocumentReferenceWeb extends DocumentReference { + /// instance of Firestore from the web plugin final web.Firestore firestoreWeb; + + /// instance of DocumentReference from the web plugin final web.DocumentReference delegate; + /// Creates an instance of [CollectionReferenceWeb] which represents path + /// at [pathComponents] and uses implementation of [firestoreWeb] DocumentReferenceWeb(this.firestoreWeb, FirestorePlatform firestore, List pathComponents) : delegate = firestoreWeb.doc(pathComponents.join("/")), diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 609c6045d847..87a0b6c57302 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -1,5 +1,7 @@ part of cloud_firestore_web; +/// An implementation of [FieldValueFactory] which builds [FieldValue] +/// instance that is [jsify] friendly class FieldValueFactoryWeb implements FieldValueFactory { @override FieldValueInterface arrayRemove(List elements) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index 96b65798c0db..c255d0dad17d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -1,5 +1,7 @@ part of cloud_firestore_web; +/// Implementation of [FieldValue] that is compatible with +/// firestore web plugin class FieldValueWeb implements FieldValueInterface, web.FieldValue { web.FieldValue _delegate; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 96ee24385210..24291cbeb8b0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -6,6 +6,7 @@ import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; +import 'package:js/js_util.dart'; import 'package:meta/meta.dart'; part 'collection_reference_web.dart'; @@ -24,14 +25,20 @@ part 'field_value_web.dart'; part 'write_batch_web.dart'; +/// Web implementation for [FirestorePlatform] +/// delegates calls to firestore web plugin class FirestoreWeb extends FirestorePlatform { + /// instance of Firestore from the web plugin final Firestore webFirestore; + /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { FirestorePlatform.instance = FirestoreWeb(); FieldValueFactory.instance = FieldValueFactoryWeb(); } + /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance + /// If [app] is null then the created instance will use the default [FirebaseApp] FirestoreWeb({FirebaseApp app}) : webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 3eae61dc9d7c..965757d37698 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -257,7 +257,9 @@ class QueryWeb implements Query { @override Map get parameters => Map(); + // disabling lint as it's only visible for testing @visibleForTesting + // ignore: public_member_api_docs QueryWeb resetQueryDelegate() => QueryWeb(firestore, pathComponents.join("/"), _webQuery); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index cbf80236e428..cfbe94150b3f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -1,5 +1,6 @@ part of cloud_firestore_web; +/// A web specific for [Transaction] class TransactionWeb implements Transaction { final web.Transaction _webTransaction; @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 28ffea432d79..6f69c82c98ef 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -1,6 +1,8 @@ part of cloud_firestore_web; +// disabling lint as it's only visible for testing @visibleForTesting +// ignore: public_member_api_docs class CodecUtility { static Map encodeMapData(Map data) { if (data == null) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 4874a81e853c..b17a7ca2c97d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -1,5 +1,6 @@ part of cloud_firestore_web; +/// A web specific for [WriteBatch] class WriteBatchWeb implements WriteBatch { final web.WriteBatch _delegate; From 37f7bd033288291200683e40e47c7a858f6bd2c8 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 18:13:58 +0000 Subject: [PATCH 089/144] added TransactionWeb unit test --- .../lib/firestore_web.dart | 2 +- .../lib/transaction_web.dart | 4 +- .../test/collection_reference_web_test.dart | 2 +- .../test/document_reference_web_test.dart | 8 +-- .../test/query_web_test.dart | 2 +- .../cloud_firestore_web/test/test_common.dart | 12 +++- .../test/transaction_web_test.dart | 58 +++++++++++++++++++ 7 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 24291cbeb8b0..dfbd5b3d2578 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -98,7 +98,7 @@ class FirestoreWeb extends FirestorePlatform { {Duration timeout = const Duration(seconds: 5)}) async { Map result; await webFirestore.runTransaction((transaction) async { - result = await transactionHandler(TransactionWeb._(transaction, this)); + result = await transactionHandler(TransactionWeb(transaction, this)); }).timeout(timeout); return result is Map ? result : {}; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index cfbe94150b3f..0957eb4d373e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -6,7 +6,9 @@ class TransactionWeb implements Transaction { @override FirestorePlatform firestore; - TransactionWeb._(this._webTransaction, this.firestore); + // ignore: public_member_api_docs + @visibleForTesting + TransactionWeb(this._webTransaction, this.firestore); @override String get appName => firestore.appName(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index e4da0ec47570..fe86fccf42f5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -9,7 +9,7 @@ import 'test_common.dart'; void main() { group("$CollectionReferenceWeb()", () { - final mockDocumentReference = MockDocumentReference(); + final mockDocumentReference = MockWebDocumentReference(); CollectionReferenceWeb collectionReference; setUp(() { final mockFirestoreWeb = mockFirestore(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart index 1d3039988ea7..91513296e2d9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -1,5 +1,3 @@ -import 'dart:html'; - @TestOn('chrome') import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; @@ -10,13 +8,9 @@ import 'test_common.dart'; const _kPath = "test/document"; -class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} - -class MockWebSnapshotMetaData extends Mock implements web.SnapshotMetadata {} - void main() { group("$DocumentReferenceWeb()", () { - final mockWebDocumentReferences = MockDocumentReference(); + final mockWebDocumentReferences = MockWebDocumentReference(); DocumentReferenceWeb documentRefernce; setUp(() { final mockWebFirestore = mockFirestore(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index b423cb4d2f48..e21740b67d6b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -46,7 +46,7 @@ void main() { when(mockMetaData.fromCache).thenReturn(true); when(mockMetaData.hasPendingWrites).thenReturn(false); - final mockDocumentReference = MockDocumentReference(); + final mockDocumentReference = MockWebDocumentReference(); when(mockDocumentReference.path).thenReturn("test/reference"); final mockDocumentSnapshot = MockWebDocumentSnapshot(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 8dca6a555482..3c8aae4dc946 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -8,9 +8,19 @@ import 'package:firebase/firestore.dart' as web; const kCollectionId = "test"; +class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} + +class MockWebSnapshotMetaData extends Mock implements web.SnapshotMetadata {} + class MockFirestoreWeb extends Mock implements web.Firestore {} -class MockDocumentReference extends Mock implements web.DocumentReference {} +class MockWebTransaction extends Mock implements web.Transaction {} + +class MockDocumentReference extends Mock implements DocumentReferenceWeb {} + +class MockFirestore extends Mock implements FirestoreWeb {} + +class MockWebDocumentReference extends Mock implements web.DocumentReference {} class MockQueryWeb extends Mock implements QueryWeb {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart new file mode 100644 index 000000000000..39dd5d94dbbd --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -0,0 +1,58 @@ +@TestOn("chrome") +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'test_common.dart'; + +void main() { + group("TransactionWeb", () { + final mockWebTransaction = MockWebTransaction(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockDocumentReference = MockDocumentReference(); + final mockFirestore = MockFirestore(); + final transaction = TransactionWeb(mockWebTransaction, mockFirestore); + + setUp(() { + when(mockFirestore.appName()).thenReturn("test"); + when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); + }); + + test("appName", () { + expect(transaction.appName, equals("test")); + verify(mockFirestore.appName()); + }); + + test("delete", () async { + await transaction.delete(mockDocumentReference); + verify(mockWebTransaction.delete(mockWebDocumentReference)); + }); + + test("get", () async { + final mockWebSnapshot = MockWebDocumentSnapshot(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockWebSnapshotMetaData = MockWebSnapshotMetaData(); + when(mockWebSnapshotMetaData.hasPendingWrites).thenReturn(true); + when(mockWebSnapshotMetaData.fromCache).thenReturn(true); + when(mockWebDocumentReference.path).thenReturn("test/path"); + when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReference); + when(mockWebSnapshot.data()).thenReturn(Map()); + when(mockWebSnapshot.metadata).thenReturn(mockWebSnapshotMetaData); + + when(mockWebTransaction.get(any)) + .thenAnswer((_) => Future.value(mockWebSnapshot)); + await transaction.get(mockDocumentReference); + verify(mockWebTransaction.get(any)); + }); + + test("set", () async { + await transaction.set(mockDocumentReference, {}); + verify(mockWebTransaction.set(mockWebDocumentReference, {})); + }); + + test("update", () async { + await transaction.update(mockDocumentReference, {}); + verify(mockWebTransaction.update(mockWebDocumentReference, + data: argThat(equals({}), named: "data"))); + }); + }); +} From a771d889a75165d766ab1ef37cfa798f6ddb2cc8 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 22 Dec 2019 18:29:26 +0000 Subject: [PATCH 090/144] Added WriteBatchTest --- .../lib/firestore_web.dart | 2 +- .../lib/utils/codec_utility.dart | 18 +++++++++ .../lib/write_batch_web.dart | 8 ++-- .../test/codec_utility_test.dart | 3 +- .../test/field_value_factory_web_test.dart | 1 + .../test/query_web_test.dart | 1 - .../cloud_firestore_web/test/test_common.dart | 2 + .../test/transaction_web_test.dart | 2 +- .../test/write_batch_web_test.dart | 37 +++++++++++++++++++ 9 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index dfbd5b3d2578..786187159528 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -63,7 +63,7 @@ class FirestoreWeb extends FirestorePlatform { DocumentReferenceWeb(webFirestore, this, path.split('/')); @override - WriteBatch batch() => WriteBatchWeb._(webFirestore.batch()); + WriteBatch batch() => WriteBatchWeb(webFirestore.batch()); @override Future enablePersistence(bool enable) async { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 6f69c82c98ef..a86fecdcb263 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -4,6 +4,9 @@ part of cloud_firestore_web; @visibleForTesting // ignore: public_member_api_docs class CodecUtility { + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static Map encodeMapData(Map data) { if (data == null) { return null; @@ -13,6 +16,9 @@ class CodecUtility { return output; } + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static List encodeArrayData(List data) { if (data == null) { return null; @@ -20,6 +26,9 @@ class CodecUtility { return List.from(data).map(valueEncode).toList(); } + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static dynamic valueEncode(dynamic value) { if (value is FieldValueInterface && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb)._delegate; @@ -37,6 +46,9 @@ class CodecUtility { return value; } + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static Map decodeMapData(Map data) { if (data == null) { return null; @@ -46,6 +58,9 @@ class CodecUtility { return output; } + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static List decodeArrayData(List data) { if (data == null) { return null; @@ -53,6 +68,9 @@ class CodecUtility { return List.from(data).map(valueDecode).toList(); } + // disabling lint as it's only visible for testing + @visibleForTesting +// ignore: public_member_api_docs static dynamic valueDecode(dynamic value) { if (value is web.GeoPoint) { return GeoPoint(value.latitude, value.longitude); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index b17a7ca2c97d..369072708ce4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -4,7 +4,9 @@ part of cloud_firestore_web; class WriteBatchWeb implements WriteBatch { final web.WriteBatch _delegate; - WriteBatchWeb._(this._delegate); + // ignore: public_member_api_docs + @visibleForTesting + WriteBatchWeb(this._delegate); @override Future commit() async { @@ -30,7 +32,7 @@ class WriteBatchWeb implements WriteBatch { @override void updateData(DocumentReference document, Map data) { assert(document is DocumentReferenceWeb); - _delegate.set((document as DocumentReferenceWeb).delegate, - CodecUtility.encodeMapData(data)); + _delegate.update((document as DocumentReferenceWeb).delegate, + data: CodecUtility.encodeMapData(data)); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index 7fcecee03aa8..fbd3c06fdbd8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -1,6 +1,5 @@ -import 'dart:typed_data'; - @TestOn("chrome") +import 'dart:typed_data'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart index 4b114153caac..d4c18f33301d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -1,3 +1,4 @@ +@TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index e21740b67d6b..f3b52c2ff779 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -4,7 +4,6 @@ import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:firebase/firestore.dart' as web; -import 'document_reference_web_test.dart'; import 'test_common.dart'; class MockWebQuery extends Mock implements web.Query {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 3c8aae4dc946..967ed27a9994 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -16,6 +16,8 @@ class MockFirestoreWeb extends Mock implements web.Firestore {} class MockWebTransaction extends Mock implements web.Transaction {} +class MockWebWriteBatch extends Mock implements web.WriteBatch {} + class MockDocumentReference extends Mock implements DocumentReferenceWeb {} class MockFirestore extends Mock implements FirestoreWeb {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index 39dd5d94dbbd..fa938a695dd8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -5,7 +5,7 @@ import 'package:mockito/mockito.dart'; import 'test_common.dart'; void main() { - group("TransactionWeb", () { + group("$TransactionWeb()", () { final mockWebTransaction = MockWebTransaction(); final mockWebDocumentReference = MockWebDocumentReference(); final mockDocumentReference = MockDocumentReference(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart new file mode 100644 index 000000000000..b96c1f8ed0d5 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -0,0 +1,37 @@ +@TestOn("chrome") +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'test_common.dart'; + +void main() { + group("$WriteBatch()", () { + final mockWebTransaction = MockWebWriteBatch(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockDocumentReference = MockDocumentReference(); + final mockFirestore = MockFirestore(); + final transaction = WriteBatchWeb(mockWebTransaction); + + setUp(() { + when(mockFirestore.appName()).thenReturn("test"); + when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); + }); + + test("delete", () async { + await transaction.delete(mockDocumentReference); + verify(mockWebTransaction.delete(mockWebDocumentReference)); + }); + + test("setData", () async { + await transaction.setData(mockDocumentReference, {}); + verify(mockWebTransaction.set(mockWebDocumentReference, {}, null)); + }); + + test("updateData", () async { + await transaction.updateData(mockDocumentReference, {}); + verify(mockWebTransaction.update(mockWebDocumentReference, + data: argThat(equals({}), named: "data"))); + }); + }); +} From 49edadaaa1ca5cc6819cab7ef6b6a08efb7aed15 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 23 Dec 2019 07:49:41 +0000 Subject: [PATCH 091/144] Added visiblefortesting annotation --- .../lib/src/firestore_message_codec.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index dc6569668610..4af6cb60161b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -8,6 +8,7 @@ part of cloud_firestore_platform_interface; // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs class FirestoreMessageCodec extends StandardMessageCodec { + @visibleForTesting // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs const FirestoreMessageCodec(); From 50ef0f157b70522b70c9f3a58e212727d34de902 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Mon, 23 Dec 2019 07:50:05 +0000 Subject: [PATCH 092/144] Fix analyzer --- .../lib/src/firestore_message_codec.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index 4af6cb60161b..8cd8dc42921e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -8,9 +8,10 @@ part of cloud_firestore_platform_interface; // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs class FirestoreMessageCodec extends StandardMessageCodec { - @visibleForTesting + // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs + @visibleForTesting const FirestoreMessageCodec(); static const int _kDateTime = 128; From 566e011b722882f4a9d6e11a01aa6feb894ebfd1 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 3 Jan 2020 20:11:45 +0000 Subject: [PATCH 093/144] Delete unnecessary timestamp.dart --- .../cloud_firestore/lib/cloud_firestore.dart | 18 +++- .../cloud_firestore/lib/src/timestamp.dart | 98 ------------------- .../lib/src/firestore_message_codec.dart | 1 - 3 files changed, 15 insertions(+), 102 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/timestamp.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index d81fe4da1207..da795fb0945e 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -5,7 +5,7 @@ library cloud_firestore; import 'dart:async'; -import 'dart:ui' show hashValues, hashList; +import 'dart:ui' show hashList; import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' @@ -15,20 +15,32 @@ import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' - show FieldPath, Blob, GeoPoint; + show FieldPath, Blob, GeoPoint, Timestamp; part 'src/collection_reference.dart'; + part 'src/document_change.dart'; + part 'src/utils/platform_utils.dart'; + part 'src/document_reference.dart'; + part 'src/document_snapshot.dart'; + part 'src/field_value.dart'; + part 'src/firestore.dart'; + part 'src/query.dart'; + part 'src/query_snapshot.dart'; + part 'src/utils/codec_utility.dart'; + part 'src/snapshot_metadata.dart'; -part 'src/timestamp.dart'; + part 'src/transaction.dart'; + part 'src/write_batch.dart'; + part 'src/source.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/timestamp.dart b/packages/cloud_firestore/cloud_firestore/lib/src/timestamp.dart deleted file mode 100644 index 027f5a55ed76..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/timestamp.dart +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2018, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -const int _kThousand = 1000; -const int _kMillion = 1000000; -const int _kBillion = 1000000000; - -void _check(bool expr, String name, int value) { - if (!expr) { - throw ArgumentError("Timestamp $name out of range: $value"); - } -} - -/// A Timestamp represents a point in time independent of any time zone or calendar, -/// represented as seconds and fractions of seconds at nanosecond resolution in UTC -/// Epoch time. It is encoded using the Proleptic Gregorian Calendar which extends -/// the Gregorian calendar backwards to year one. It is encoded assuming all minutes -/// are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second table -/// is needed for interpretation. Range is from 0001-01-01T00:00:00Z to -/// 9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we -/// can convert to and from RFC 3339 date strings. -/// -/// For more information, see [the reference timestamp definition](https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto) -class Timestamp implements Comparable { - Timestamp(this._seconds, this._nanoseconds) { - _validateRange(_seconds, _nanoseconds); - } - - factory Timestamp.fromMillisecondsSinceEpoch(int milliseconds) { - final int seconds = (milliseconds / _kThousand).floor(); - final int nanoseconds = (milliseconds - seconds * _kThousand) * _kMillion; - return Timestamp(seconds, nanoseconds); - } - - factory Timestamp.fromMicrosecondsSinceEpoch(int microseconds) { - final int seconds = (microseconds / _kMillion).floor(); - final int nanoseconds = (microseconds - seconds * _kMillion) * _kThousand; - return Timestamp(seconds, nanoseconds); - } - - factory Timestamp.fromDate(DateTime date) { - return Timestamp.fromMicrosecondsSinceEpoch(date.microsecondsSinceEpoch); - } - - factory Timestamp.now() { - return Timestamp.fromMicrosecondsSinceEpoch( - DateTime.now().microsecondsSinceEpoch); - } - - final int _seconds; - final int _nanoseconds; - - static const int _kStartOfTime = -62135596800; - static const int _kEndOfTime = 253402300800; - - int get seconds => _seconds; - - int get nanoseconds => _nanoseconds; - - int get millisecondsSinceEpoch => - (seconds * _kThousand + nanoseconds / _kMillion).floor(); - - int get microsecondsSinceEpoch => - (seconds * _kMillion + nanoseconds / _kThousand).floor(); - - DateTime toDate() { - return DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch); - } - - @override - int get hashCode => hashValues(seconds, nanoseconds); - @override - bool operator ==(dynamic o) => - o is Timestamp && o.seconds == seconds && o.nanoseconds == nanoseconds; - @override - int compareTo(Timestamp other) { - if (seconds == other.seconds) { - return nanoseconds.compareTo(other.nanoseconds); - } - - return seconds.compareTo(other.seconds); - } - - @override - String toString() { - return "Timestamp(seconds=$seconds, nanoseconds=$nanoseconds)"; - } - - static void _validateRange(int seconds, int nanoseconds) { - _check(nanoseconds >= 0, 'nanoseconds', nanoseconds); - _check(nanoseconds < _kBillion, 'nanoseconds', nanoseconds); - _check(seconds >= _kStartOfTime, 'seconds', seconds); - _check(seconds < _kEndOfTime, 'seconds', seconds); - } -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index 8cd8dc42921e..c87d1812a15c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -8,7 +8,6 @@ part of cloud_firestore_platform_interface; // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs class FirestoreMessageCodec extends StandardMessageCodec { - // ignoring lint rule here as it's only visible for testing // ignore: public_member_api_docs @visibleForTesting From b2b445c42400600196594f17fbfe9e4cbe2f876a Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 3 Jan 2020 20:37:15 +0000 Subject: [PATCH 094/144] Handle DateTime to Timestamp conversion for web --- .../lib/utils/codec_utility.dart | 16 ++++++++++------ .../test/codec_utility_test.dart | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index a86fecdcb263..9280029ef062 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -6,7 +6,7 @@ part of cloud_firestore_web; class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static Map encodeMapData(Map data) { if (data == null) { return null; @@ -18,7 +18,7 @@ class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static List encodeArrayData(List data) { if (data == null) { return null; @@ -28,10 +28,12 @@ class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static dynamic valueEncode(dynamic value) { if (value is FieldValueInterface && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb)._delegate; + } else if (value is Timestamp) { + return value.toDate(); } else if (value is GeoPoint) { return web.GeoPoint(value.latitude, value.longitude); } else if (value is Blob) { @@ -48,7 +50,7 @@ class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static Map decodeMapData(Map data) { if (data == null) { return null; @@ -60,7 +62,7 @@ class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static List decodeArrayData(List data) { if (data == null) { return null; @@ -70,10 +72,12 @@ class CodecUtility { // disabling lint as it's only visible for testing @visibleForTesting -// ignore: public_member_api_docs + // ignore: public_member_api_docs static dynamic valueDecode(dynamic value) { if (value is web.GeoPoint) { return GeoPoint(value.latitude, value.longitude); + } else if (value is DateTime) { + return Timestamp.fromDate(value); } else if (value is web.Blob) { return Blob(value.toUint8Array()); } else if (value is web.DocumentReference) { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index fbd3c06fdbd8..5754930761d9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -40,6 +40,10 @@ void main() { CodecUtility.encodeMapData({'test': mockFieldValueInterface}); verify(mockFieldValueInterface.instance); + final timeStamp = Timestamp.now(); + final result = CodecUtility.encodeMapData({'test': timeStamp}); + expect(result['test'], isInstanceOf()); + //GeoPoint final mockGeoPoint = MockGeoPoint(); CodecUtility.encodeMapData({'test': mockGeoPoint}); @@ -79,6 +83,10 @@ void main() { CodecUtility.encodeArrayData([mockFieldValueInterface]); verify(mockFieldValueInterface.instance); + final timeStamp = Timestamp.now(); + final result = CodecUtility.encodeArrayData([timeStamp]); + expect(result.first, isInstanceOf()); + //GeoPoint final mockGeoPoint = MockGeoPoint(); CodecUtility.encodeArrayData([mockGeoPoint]); @@ -120,6 +128,10 @@ void main() { isInstanceOf()); verify(mockWebBlob.toUint8Array()); + final date = DateTime.now(); + expect(CodecUtility.decodeMapData({'test': date})['test'], + isInstanceOf()); + //GeoPoint final mockWebGeoPoint = MockWebGeoPoint(); expect(CodecUtility.decodeMapData({'test': mockWebGeoPoint})['test'], @@ -151,6 +163,10 @@ void main() { isInstanceOf()); verify(mockWebBlob.toUint8Array()); + final date = DateTime.now(); + expect(CodecUtility.decodeArrayData([date]).first, + isInstanceOf()); + //GeoPoint final mockWebGeoPoint = MockWebGeoPoint(); expect(CodecUtility.decodeArrayData([mockWebGeoPoint]).first, From 9b786dbe6a0cbe1e8cded1f2b1907b625d479145 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 3 Jan 2020 21:19:13 +0000 Subject: [PATCH 095/144] Use codec_utility across web --- .../lib/document_reference_web.dart | 18 +++++------------- .../lib/firestore_web.dart | 2 ++ .../cloud_firestore_web/lib/query_web.dart | 19 +++++++------------ .../lib/transaction_web.dart | 13 ++----------- .../lib/utils/document_reference_utils.dart | 14 ++++++++++++++ 5 files changed, 30 insertions(+), 36 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 66acc7854fe8..5d2a1ac40172 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -26,7 +26,8 @@ class DocumentReferenceWeb extends DocumentReference { @override Future get({Source source = Source.serverAndCache}) async { - return _fromWeb(await delegate.get()); + return _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + await delegate.get(), this.firestore); } @override @@ -38,17 +39,8 @@ class DocumentReferenceWeb extends DocumentReference { if (includeMetadataChanges) { querySnapshots = delegate.onMetadataChangesSnapshot; } - return querySnapshots.map(_fromWeb); + return querySnapshots.map((webSnapshot) => + _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this.firestore)); } - - /// Builds [DocumentSnapshot] instance form web snapshot instance - DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => - DocumentSnapshot( - webSnapshot.ref.path, - CodecUtility.decodeMapData(webSnapshot.data()), - SnapshotMetadata( - webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache, - ), - this.firestore); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 786187159528..75e0285b1615 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -13,6 +13,8 @@ part 'collection_reference_web.dart'; part 'utils/codec_utility.dart'; +part 'utils/document_reference_utils.dart'; + part 'field_value_factory_web.dart'; part 'document_reference_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index 965757d37698..dfac4340ac4b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -213,7 +213,11 @@ class QueryWeb implements Query { QuerySnapshot _webQuerySnapshotToQuerySnapshot( web.QuerySnapshot webSnapshot) { return QuerySnapshot( - webSnapshot.docs.map(_webDocumentSnapshotToDocumentSnapshot).toList(), + webSnapshot.docs + .map((webSnapshot) => + _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this._firestore)) + .toList(), webSnapshot.docChanges().map(_webChangeToChange).toList(), _webMetadataToMetada(webSnapshot.metadata)); } @@ -223,7 +227,8 @@ class QueryWeb implements Query { _fromString(webChange.type), webChange.oldIndex, webChange.newIndex, - _webDocumentSnapshotToDocumentSnapshot(webChange.doc)); + _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webChange.doc, this._firestore)); } DocumentChangeType _fromString(String item) { @@ -239,16 +244,6 @@ class QueryWeb implements Query { } } - DocumentSnapshot _webDocumentSnapshotToDocumentSnapshot( - web.DocumentSnapshot webSnapshot) { - return DocumentSnapshot( - webSnapshot.ref.path, - webSnapshot.data(), - SnapshotMetadata(webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache), - this._firestore); - } - SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { return SnapshotMetadata( webMetadata.hasPendingWrites, webMetadata.fromCache); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 0957eb4d373e..5d2a4f322a0d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -25,7 +25,8 @@ class TransactionWeb implements Transaction { assert(documentReference is DocumentReferenceWeb); final webSnapshot = await _webTransaction .get((documentReference as DocumentReferenceWeb).delegate); - return _fromWeb(webSnapshot); + return _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this.firestore); } @override @@ -46,16 +47,6 @@ class TransactionWeb implements Transaction { data: CodecUtility.encodeMapData(data)); } - DocumentSnapshot _fromWeb(web.DocumentSnapshot webSnapshot) => - DocumentSnapshot( - webSnapshot.ref.path, - CodecUtility.decodeMapData(webSnapshot.data()), - SnapshotMetadata( - webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache, - ), - this.firestore); - @override Future finish() { return Future.value(); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart new file mode 100644 index 000000000000..1282a390da18 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart @@ -0,0 +1,14 @@ +part of cloud_firestore_web; + +/// Builds [DocumentSnapshot] instance form web snapshot instance +DocumentSnapshot _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + web.DocumentSnapshot webSnapshot, FirestorePlatform firestore) { + return DocumentSnapshot( + webSnapshot.ref.path, + CodecUtility.decodeMapData(webSnapshot.data()), + SnapshotMetadata( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + firestore); +} From 24adc0c727fbd176427c0905b112bf697e62281d Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 3 Jan 2020 23:26:18 +0000 Subject: [PATCH 096/144] Avoid building unnecessary instances of FirebaseApp --- .../lib/src/collection_reference.dart | 7 +- .../lib/src/document_change.dart | 6 +- .../lib/src/document_reference.dart | 13 ++-- .../lib/src/document_snapshot.dart | 8 +- .../cloud_firestore/lib/src/firestore.dart | 9 ++- .../cloud_firestore/lib/src/query.dart | 78 ++++++++++--------- .../lib/src/query_snapshot.dart | 13 ++-- .../cloud_firestore/lib/src/transaction.dart | 6 +- .../lib/src/utils/codec_utility.dart | 19 +++-- 9 files changed, 90 insertions(+), 69 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index 0060deaaae65..d86237edb1f9 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -10,7 +10,8 @@ part of cloud_firestore; class CollectionReference extends Query { final platform.CollectionReference _delegate; - CollectionReference._(this._delegate) : super._(_delegate); + CollectionReference._(this._delegate, Firestore firestore) + : super._(_delegate, firestore); /// ID of the referenced collection. String get id => _pathComponents.isEmpty ? null : _pathComponents.last; @@ -22,7 +23,7 @@ class CollectionReference extends Query { if (_pathComponents.length < 2) { return null; } - return DocumentReference._(_delegate.parent()); + return DocumentReference._(_delegate.parent(), firestore); } /// A string containing the slash-separated path to this CollectionReference @@ -36,7 +37,7 @@ class CollectionReference extends Query { /// The unique key generated is prefixed with a client-generated timestamp /// so that the resulting list will be chronologically-sorted. DocumentReference document([String path]) => - DocumentReference._(_delegate.document(path)); + DocumentReference._(_delegate.document(path), firestore); /// Returns a `DocumentReference` with an auto-generated ID, after /// populating it with provided [data]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 20ecb01fe4d3..058f1f270239 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -24,8 +24,9 @@ enum DocumentChangeType { /// (added, modified, or removed). class DocumentChange { final platform.DocumentChange _delegate; + final Firestore _firestore; - DocumentChange._(this._delegate); + DocumentChange._(this._delegate, this._firestore); /// The type of change that occurred (added, modified, or removed). DocumentChangeType get type => _PlatformUtils.fromPlatform(_delegate.type); @@ -45,5 +46,6 @@ class DocumentChange { int get newIndex => _delegate.newIndex; /// The document affected by this change. - DocumentSnapshot get document => DocumentSnapshot._(_delegate.document); + DocumentSnapshot get document => + DocumentSnapshot._(_delegate.document, _firestore); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 2fac0defe569..1ebc94483443 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -12,11 +12,11 @@ part of cloud_firestore; /// to a subcollection. class DocumentReference { platform.DocumentReference _delegate; - DocumentReference._(this._delegate); /// The Firestore instance associated with this document reference - Firestore get firestore => - Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); + final Firestore firestore; + + DocumentReference._(this._delegate, this.firestore); @override bool operator ==(dynamic o) => @@ -27,7 +27,7 @@ class DocumentReference { /// Parent returns the containing [CollectionReference]. CollectionReference parent() { - return CollectionReference._(_delegate.parent()); + return CollectionReference._(_delegate.parent(), firestore); } /// Slash-delimited path representing the database location of this query. @@ -63,7 +63,8 @@ class DocumentReference { /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { return DocumentSnapshot._( - await _delegate.get(source: _PlatformUtils.toPlatformSource(source))); + await _delegate.get(source: _PlatformUtils.toPlatformSource(source)), + firestore); } /// Deletes the document referred to by this [DocumentReference]. @@ -81,5 +82,5 @@ class DocumentReference { Stream snapshots({bool includeMetadataChanges = false}) => _delegate .snapshots(includeMetadataChanges: includeMetadataChanges) - .map((snapshot) => DocumentSnapshot._(snapshot)); + .map((snapshot) => DocumentSnapshot._(snapshot, firestore)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 4d7e66c7684e..9697b96ea515 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -11,9 +11,9 @@ part of cloud_firestore; /// syntax to access a specific field. class DocumentSnapshot { platform.DocumentSnapshot _delegate; - Firestore get _firestore => - Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); - DocumentSnapshot._(this._delegate); + final Firestore _firestore; + + DocumentSnapshot._(this._delegate, this._firestore); /// The reference that produced this snapshot DocumentReference get reference => @@ -21,7 +21,7 @@ class DocumentSnapshot { /// Contains all the data of this snapshot Map get data => - _CodecUtility.replaceDelegatesWithValueInMap(_delegate.data); + _CodecUtility.replaceDelegatesWithValueInMap(_delegate.data, _firestore); /// Metadata about this snapshot concerning its source and if it has local /// modifications. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 0d4fdbd30870..9a47f01a6bc6 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -9,6 +9,7 @@ part of cloud_firestore; /// You can get an instance by calling [Firestore.instance]. class Firestore { platform.FirestorePlatform _delegatePackingProperty; + platform.FirestorePlatform get _delegate { if (_delegatePackingProperty == null) { _delegatePackingProperty = platform.FirestorePlatform.instance; @@ -43,16 +44,16 @@ class Firestore { /// Gets a [CollectionReference] for the specified Firestore path. CollectionReference collection(String path) { assert(path != null); - return CollectionReference._(_delegate.collection(path)); + return CollectionReference._(_delegate.collection(path), this); } /// Gets a [Query] for the specified collection group. Query collectionGroup(String path) => - Query._(_delegate.collectionGroup(path)); + Query._(_delegate.collectionGroup(path), this); /// Gets a [DocumentReference] for the specified Firestore path. DocumentReference document(String path) => - DocumentReference._(_delegate.document(path)); + DocumentReference._(_delegate.document(path), this); @Deprecated('Use the persistenceEnabled parameter of the [settings] method') Future enablePersistence(bool enable) => @@ -84,7 +85,7 @@ class Firestore { {Duration timeout = const Duration(seconds: 5)}) { return _delegate.runTransaction( (platformTransaction) => - transactionHandler(Transaction._(platformTransaction)), + transactionHandler(Transaction._(platformTransaction, this)), timeout: timeout); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index ce1bd2b8ab69..a4be74091c40 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -8,11 +8,10 @@ part of cloud_firestore; class Query { final platform.Query _delegate; - Query._(this._delegate); - /// The Firestore instance associated with this query - Firestore get firestore => - Firestore(app: FirebaseApp(name: this._delegate.firestore.app.name)); + final Firestore firestore; + + Query._(this._delegate, this.firestore); List get _pathComponents => _delegate.pathComponents; @@ -26,7 +25,7 @@ class Query { Stream snapshots({bool includeMetadataChanges = false}) => _delegate .snapshots(includeMetadataChanges: includeMetadataChanges) - .map((item) => QuerySnapshot._(item)); + .map((item) => QuerySnapshot._(item, firestore)); /// Fetch the documents for this query Future getDocuments( @@ -34,12 +33,12 @@ class Query { assert(source != null); final docs = await _delegate.getDocuments( source: _PlatformUtils.toPlatformSource(source)); - return QuerySnapshot._(docs); + return QuerySnapshot._(docs, firestore); } /// Obtains a CollectionReference corresponding to this query's location. CollectionReference reference() => - CollectionReference._(_delegate.reference()); + CollectionReference._(_delegate.reference(), firestore); /// Creates and returns a new [Query] with additional filter on specified /// [field]. [field] refers to a field in a document. @@ -64,16 +63,18 @@ class Query { List whereIn, bool isNull, }) => - Query._(_delegate.where(field, - isEqualTo: isEqualTo, - isLessThan: isLessThan, - isLessThanOrEqualTo: isLessThanOrEqualTo, - isGreaterThan: isGreaterThan, - isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, - arrayContainsAny: arrayContainsAny, - arrayContains: arrayContains, - whereIn: whereIn, - isNull: isNull)); + Query._( + _delegate.where(field, + isEqualTo: isEqualTo, + isLessThan: isLessThan, + isLessThanOrEqualTo: isLessThanOrEqualTo, + isGreaterThan: isGreaterThan, + isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, + arrayContainsAny: arrayContainsAny, + arrayContains: arrayContains, + whereIn: whereIn, + isNull: isNull), + firestore); /// Creates and returns a new [Query] that's additionally sorted by the specified /// [field]. @@ -86,7 +87,7 @@ class Query { /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. Query orderBy(dynamic field, {bool descending = false}) => - Query._(_delegate.orderBy(field, descending: descending)); + Query._(_delegate.orderBy(field, descending: descending), firestore); /// Creates and returns a new [Query] that starts after the provided document /// (exclusive). The starting position is relative to the order of the query. @@ -102,9 +103,10 @@ class Query { /// * [endAfterDocument] for a query that ends after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query startAfterDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAfterDocument( - _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query startAfterDocument(DocumentSnapshot documentSnapshot) => Query._( + _delegate.startAfterDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot)), + firestore); /// Creates and returns a new [Query] that starts at the provided document /// (inclusive). The starting position is relative to the order of the query. @@ -120,9 +122,10 @@ class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query startAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.startAtDocument( - _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query startAtDocument(DocumentSnapshot documentSnapshot) => Query._( + _delegate.startAtDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot)), + firestore); /// Takes a list of [values], creates and returns a new [Query] that starts /// after the provided fields relative to the order of the query. @@ -133,7 +136,7 @@ class Query { /// [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. Query startAfter(List values) => - Query._(_delegate.startAfter(values)); + Query._(_delegate.startAfter(values), firestore); /// Takes a list of [values], creates and returns a new [Query] that starts at /// the provided fields relative to the order of the query. @@ -143,7 +146,8 @@ class Query { /// Cannot be used in combination with [startAfter], [startAfterDocument], /// or [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAt(List values) => Query._(_delegate.startAt(values)); + Query startAt(List values) => + Query._(_delegate.startAt(values), firestore); /// Creates and returns a new [Query] that ends at the provided document /// (inclusive). The end position is relative to the order of the query. @@ -159,9 +163,10 @@ class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query endAtDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endAtDocument( - _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query endAtDocument(DocumentSnapshot documentSnapshot) => Query._( + _delegate.endAtDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot)), + firestore); /// Takes a list of [values], creates and returns a new [Query] that ends at the /// provided fields relative to the order of the query. @@ -171,7 +176,8 @@ class Query { /// Cannot be used in combination with [endBefore], [endBeforeDocument], or /// [endAtDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endAt(List values) => Query._(_delegate.endAt(values)); + Query endAt(List values) => + Query._(_delegate.endAt(values), firestore); /// Creates and returns a new [Query] that ends before the provided document /// (exclusive). The end position is relative to the order of the query. @@ -187,9 +193,10 @@ class Query { /// * [startAfterDocument] for a query that starts after document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query endBeforeDocument(DocumentSnapshot documentSnapshot) => - Query._(_delegate.endBeforeDocument( - _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot))); + Query endBeforeDocument(DocumentSnapshot documentSnapshot) => Query._( + _delegate.endBeforeDocument( + _PlatformUtils.toPlatformDocumentSnapshot(documentSnapshot)), + firestore); /// Takes a list of [values], creates and returns a new [Query] that ends before /// the provided fields relative to the order of the query. @@ -199,9 +206,10 @@ class Query { /// Cannot be used in combination with [endAt], [endBeforeDocument], or /// [endBeforeDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endBefore(List values) => Query._(_delegate.endBefore(values)); + Query endBefore(List values) => + Query._(_delegate.endBefore(values), firestore); /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. - Query limit(int length) => Query._(_delegate.limit(length)); + Query limit(int length) => Query._(_delegate.limit(length), firestore); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 89e43bf224c0..9226ed5c810c 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -7,17 +7,20 @@ part of cloud_firestore; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { final platform.QuerySnapshot _delegate; + final Firestore _firestore; - QuerySnapshot._(this._delegate); + QuerySnapshot._(this._delegate, this._firestore); /// Gets a list of all the documents included in this snapshot - List get documents => - _delegate.documents.map((item) => DocumentSnapshot._(item)).toList(); + List get documents => _delegate.documents + .map((item) => DocumentSnapshot._(item, _firestore)) + .toList(); /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. - List get documentChanges => - _delegate.documentChanges.map((item) => DocumentChange._(item)).toList(); + List get documentChanges => _delegate.documentChanges + .map((item) => DocumentChange._(item, _firestore)) + .toList(); SnapshotMetadata get metadata => SnapshotMetadata._(_delegate.metadata); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 70b308ed60ae..50de77242cf5 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -9,7 +9,9 @@ part of cloud_firestore; typedef Future TransactionHandler(Transaction transaction); class Transaction { - Transaction._(this._delegate); + final Firestore _firestore; + + Transaction._(this._delegate, this._firestore); platform.Transaction _delegate; @@ -20,7 +22,7 @@ class Transaction { Future get(DocumentReference documentReference) async { final result = await _delegate.get(documentReference._delegate); if (result != null) { - return DocumentSnapshot._(result); + return DocumentSnapshot._(result, _firestore); } else { return null; } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index bfa7b2a4788c..44b9e4cc0e63 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -19,20 +19,23 @@ class _CodecUtility { } static Map replaceDelegatesWithValueInMap( - Map data) { + Map data, Firestore firestore) { if (data == null) { return null; } Map output = Map.from(data); - output.updateAll((_, value) => valueDecode(value)); + output.updateAll((_, value) => valueDecode(value, firestore)); return output; } - static List replaceDelegatesWithValueInArray(List data) { + static List replaceDelegatesWithValueInArray( + List data, Firestore firestore) { if (data == null) { return null; } - return List.from(data).map((value) => valueDecode(value)).toList(); + return List.from(data) + .map((value) => valueDecode(value, firestore)) + .toList(); } static dynamic valueEncode(dynamic value) { @@ -46,13 +49,13 @@ class _CodecUtility { return value; } - static dynamic valueDecode(dynamic value) { + static dynamic valueDecode(dynamic value, Firestore firestore) { if (value is platform.DocumentReference) { - return DocumentReference._(value); + return DocumentReference._(value, firestore); } else if (value is List) { - return replaceDelegatesWithValueInArray(value); + return replaceDelegatesWithValueInArray(value, firestore); } else if (value is Map) { - return replaceDelegatesWithValueInMap(value); + return replaceDelegatesWithValueInMap(value, firestore); } return value; } From 19b094c51779f2195ec4877ec2604bc817e97444 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 8 Jan 2020 09:23:36 +0000 Subject: [PATCH 097/144] Added platform interface updates --- .../lib/cloud_firestore_platform_interface.dart | 13 ++++++++----- .../lib/src/document_snapshot.dart | 16 ++++++++-------- .../lib/src/firestore_message_codec.dart | 3 ++- .../src/method_channel_document_reference.dart | 2 +- .../src/method_channel_field_value_factory.dart | 4 ++-- .../lib/src/method_channel_firestore.dart | 5 +++-- .../lib/src/method_channel_query_snapshot.dart | 2 +- .../platform_interface/collection_reference.dart | 4 ++-- .../src/platform_interface/document_change.dart | 2 +- .../lib/src/transaction.dart | 5 +++-- 10 files changed, 31 insertions(+), 25 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 59da30606852..3766630fd4bc 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -43,7 +43,7 @@ part 'src/write_batch_platform_interface.dart'; /// Defines an interface to work with [FirestorePlatform] on web and mobile abstract class FirestorePlatform extends PlatformInterface { - /// [FirebaseApp] used for this firestore instance + /// The app associated with this Firestore instance. final FirebaseApp app; /// Create an instance using [app] @@ -54,11 +54,12 @@ abstract class FirestorePlatform extends PlatformInterface { static final Object _token = Object(); /// Create an instance using [app] using the existing implementation - factory FirestorePlatform.withApp({FirebaseApp app}) { + factory FirestorePlatform.instanceFor({FirebaseApp app}) { return FirestorePlatform.instance.withApp(app); } - /// return the current default [FirestorePlatform] instance + /// Returns the current default [FirestorePlatform] instance. + /// /// It will always default to [MethodChannelFirestore] /// if no web implementation was provided static FirestorePlatform get instance { @@ -145,8 +146,10 @@ abstract class FirestorePlatform extends PlatformInterface { } /// Setup [FirestorePlatform] with settings. - /// if [sslEnabled] has value the [host] must have non-null value as well - /// if [cacheSizeBytes] is null then default values are used. + /// + /// If [sslEnabled] has a non-null value, the [host] must have non-null value as well. + /// + /// If [cacheSizeBytes] is `null`, then default values are used. Future settings( {bool persistenceEnabled, String host, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index d4c9fe81b6b2..2036635858e6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -4,34 +4,34 @@ part of cloud_firestore_platform_interface; -/// A DocumentSnapshot contains data read from a document in your Firestore +/// Contains data read from a document in your Firestore /// database. /// -/// The data can be extracted with the data property or by using subscript +/// The data can be extracted with the [data] property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { - /// Create instance of [DocumentSnapshot] + /// Constructs a [DocumentSnapshot] using the provided [FirestorePlatform]. DocumentSnapshot(this._path, this.data, this.metadata, this.firestore); final String _path; - /// instance of the underlying [FirestorePlatform] app used + /// The [FirestorePlatform] used to produce this [DocumentSnapshot]. final FirestorePlatform firestore; - /// The reference that produced this snapshot + /// The reference that produced this snapshot. DocumentReference get reference => firestore.document(_path); - /// Contains all the data of this snapshot + /// Contains all the data of this snapshot. final Map data; /// Metadata about this snapshot concerning its source and if it has local /// modifications. final SnapshotMetadata metadata; - /// Reads individual values from the snapshot + /// Reads individual values from the snapshot. dynamic operator [](String key) => data[key]; - /// Returns the ID of the snapshot's document + /// The database ID of the snapshot's document. String get documentID => _path.split('/').last; /// Returns `true` if the document exists. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart index c87d1812a15c..8bb6b39dc2ed 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart @@ -94,7 +94,8 @@ class FirestoreMessageCodec extends StandardMessageCodec { final String appName = utf8.decoder.convert(buffer.getUint8List(appNameLength)); final FirebaseApp app = FirebaseApp(name: appName); - final FirestorePlatform firestore = FirestorePlatform.withApp(app: app); + final FirestorePlatform firestore = + FirestorePlatform.instanceFor(app: app); final int pathLength = readSize(buffer); final String path = utf8.decoder.convert(buffer.getUint8List(pathLength)); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart index 0f3b5f3566f2..339737011c78 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart @@ -7,7 +7,7 @@ part of cloud_firestore_platform_interface; /// A [MethodChannelDocumentReference] is an implementation of [DocumentReference] /// that uses [MethodChannel] to communicate with Firebase plugins class MethodChannelDocumentReference extends DocumentReference { - /// Create a [MethodChannelDocumentReference] from [pathComponents] + /// Creates a [DocumentReference] that is implemented using [MethodChannel]. MethodChannelDocumentReference( FirestorePlatform firestore, List pathComponents) : assert(firestore != null), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart index 8e771fe00cda..e056e5f5d501 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart @@ -16,8 +16,8 @@ class MethodChannelFieldValueFactory implements FieldValueFactory { @override FieldValue increment(num value) { - // It is a compile-time error for any type other than int or double to - // attempt to extend or implement num. + // It is a compile-time error for any type other than `int` or `double` to + // attempt to extend or implement `num`. assert(value is int || value is double); if (value is double) { return FieldValue._(FieldValueType.incrementDouble, value); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 34aa3269dc14..6b91d0125ed5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -32,7 +32,7 @@ class MethodChannelFirestore extends FirestorePlatform { Transaction(transactionId, call.arguments["app"]); final dynamic result = await _transactionHandlers[transactionId](transaction); - await transaction.finish(); + await transaction._finish(); return result; } }); @@ -45,7 +45,8 @@ class MethodChannelFirestore extends FirestorePlatform { static bool _initialized = false; - /// [MethodChannel] used to communicate with the native plugin + /// The [MethodChannel] used to communicate with the native plugin + @visibleForTesting static const MethodChannel channel = MethodChannel( 'plugins.flutter.io/cloud_firestore', StandardMethodCodec(FirestoreMessageCodec()), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart index 9faa7b7c3c43..4ccc90a70367 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart @@ -4,7 +4,7 @@ part of cloud_firestore_platform_interface; -/// A QuerySnapshot contains zero or more DocumentSnapshot objects. +/// Contains zero or more [DocumentSnapshot] objects. class MethodChannelQuerySnapshot extends QuerySnapshot { /// Creates a [MethodChannelQuerySnapshot] from the given [data] MethodChannelQuerySnapshot( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index f10e47d00423..b184134e2a34 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -12,12 +12,12 @@ abstract class CollectionReference extends Query { CollectionReference(FirestorePlatform firestore, List pathComponents) : super(firestore: firestore, pathComponents: pathComponents); - /// ID of the referenced collection. + /// Identifier of the referenced collection. String get id => pathComponents.isEmpty ? null : pathComponents.last; /// For subcollections, parent returns the containing [DocumentReference]. /// - /// For root collections, null is returned. + /// For root collections, `null` is returned. DocumentReference parent() { throw UnimplementedError("parent() is not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 10baa78f6e28..eb143207aa25 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -18,7 +18,7 @@ enum DocumentChangeType { removed, } -/// A DocumentChange represents a change to the documents matching a query. +/// A change to the documents matching a query. /// /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index 578c8405205f..506708bcedc7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -18,10 +18,11 @@ class Transaction extends TransactionPlatform { transactionId, appName == FirebaseApp.defaultAppName ? FirestorePlatform.instance - : FirestorePlatform.withApp(app: FirebaseApp(name: appName))); + : FirestorePlatform.instanceFor( + app: FirebaseApp(name: appName))); /// executes all the pending operations on the transaction - Future finish() => Future.wait(_pendingResults); + Future _finish() => Future.wait(_pendingResults); @override Future _get(DocumentReference documentReference) async { From abacb4cadd11ac7710b06e05beb7fe4f8c10349f Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Wed, 8 Jan 2020 09:34:31 +0000 Subject: [PATCH 098/144] Add latest update for platform_interface --- .../cloud_firestore/lib/src/firestore.dart | 3 ++- .../lib/cloud_firestore_platform_interface.dart | 2 +- .../lib/src/method_channel_firestore.dart | 3 +-- .../lib/src/transaction.dart | 2 +- .../lib/src/transaction_platform_interface.dart | 2 +- .../test/method_channel_cloud_firestore_test.dart | 2 +- .../cloud_firestore_web/lib/firestore_web.dart | 2 +- .../cloud_firestore_web/lib/transaction_web.dart | 10 +--------- .../cloud_firestore_web/lib/write_batch_web.dart | 2 +- .../cloud_firestore_web/test/transaction_web_test.dart | 5 ----- 10 files changed, 10 insertions(+), 23 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 9a47f01a6bc6..164816103139 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -19,9 +19,10 @@ class Firestore { Firestore({FirebaseApp app}) : _delegatePackingProperty = app != null - ? platform.FirestorePlatform.withApp(app: app) + ? platform.FirestorePlatform.instanceFor(app: app) : platform.FirestorePlatform.instance; + @visibleForTesting static MethodChannel get channel => platform.MethodChannelFirestore.channel; /// Gets the instance of Firestore for the default Firebase app. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 3766630fd4bc..dc52a12f28e1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -107,7 +107,7 @@ abstract class FirestorePlatform extends PlatformInterface { /// /// Unlike transactions, write batches are persisted offline and therefore are /// preferable when you don’t need to condition your writes on read data. - WriteBatch batch() { + WriteBatchPlatform batch() { throw UnimplementedError('batch() is not implemented'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 6b91d0125ed5..3e45b877a5d1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -32,7 +32,7 @@ class MethodChannelFirestore extends FirestorePlatform { Transaction(transactionId, call.arguments["app"]); final dynamic result = await _transactionHandlers[transactionId](transaction); - await transaction._finish(); + await transaction.finish(); return result; } }); @@ -46,7 +46,6 @@ class MethodChannelFirestore extends FirestorePlatform { static bool _initialized = false; /// The [MethodChannel] used to communicate with the native plugin - @visibleForTesting static const MethodChannel channel = MethodChannel( 'plugins.flutter.io/cloud_firestore', StandardMethodCodec(FirestoreMessageCodec()), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index 506708bcedc7..984d82b8e94b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -22,7 +22,7 @@ class Transaction extends TransactionPlatform { app: FirebaseApp(name: appName))); /// executes all the pending operations on the transaction - Future _finish() => Future.wait(_pendingResults); + Future finish() => Future.wait(_pendingResults); @override Future _get(DocumentReference documentReference) async { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart index 4c0e0aa514f4..6ef0500f17da 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -6,7 +6,7 @@ part of cloud_firestore_platform_interface; /// The TransactionHandler may be executed multiple times, it should be able /// to handle multiple executions. -typedef Future TransactionHandler(Transaction transaction); +typedef Future TransactionHandler(TransactionPlatform transaction); /// a [TransactionPlatform] is a set of read and write operations on one or more documents. abstract class TransactionPlatform { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 68d495be6a87..c6a4b9e62ae8 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -204,7 +204,7 @@ void main() { group('Transaction', () { test('runTransaction', () async { final Map result = await firestore.runTransaction( - (Transaction tx) async {}, + (TransactionPlatform tx) async {}, timeout: const Duration(seconds: 3)); expect(log, [ diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 75e0285b1615..4c2c25eba540 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -65,7 +65,7 @@ class FirestoreWeb extends FirestorePlatform { DocumentReferenceWeb(webFirestore, this, path.split('/')); @override - WriteBatch batch() => WriteBatchWeb(webFirestore.batch()); + WriteBatchPlatform batch() => WriteBatchWeb(webFirestore.batch()); @override Future enablePersistence(bool enable) async { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 5d2a4f322a0d..85db4181ab04 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; /// A web specific for [Transaction] -class TransactionWeb implements Transaction { +class TransactionWeb implements TransactionPlatform { final web.Transaction _webTransaction; @override FirestorePlatform firestore; @@ -10,9 +10,6 @@ class TransactionWeb implements Transaction { @visibleForTesting TransactionWeb(this._webTransaction, this.firestore); - @override - String get appName => firestore.appName(); - @override Future delete(DocumentReference documentReference) async { assert(documentReference is DocumentReferenceWeb); @@ -46,9 +43,4 @@ class TransactionWeb implements Transaction { (documentReference as DocumentReferenceWeb).delegate, data: CodecUtility.encodeMapData(data)); } - - @override - Future finish() { - return Future.value(); - } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 369072708ce4..8b022770921d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; /// A web specific for [WriteBatch] -class WriteBatchWeb implements WriteBatch { +class WriteBatchWeb implements WriteBatchPlatform { final web.WriteBatch _delegate; // ignore: public_member_api_docs diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index fa938a695dd8..c45efc65fb8c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -17,11 +17,6 @@ void main() { when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); }); - test("appName", () { - expect(transaction.appName, equals("test")); - verify(mockFirestore.appName()); - }); - test("delete", () async { await transaction.delete(mockDocumentReference); verify(mockWebTransaction.delete(mockWebDocumentReference)); From e7204f23d454b79a8ed4916535f9a03080800f3b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 17 Jan 2020 07:39:51 +0000 Subject: [PATCH 099/144] Use platform interface types in cloud_firestore --- .../cloud_firestore/cloud_firestore/lib/src/transaction.dart | 2 +- .../cloud_firestore/cloud_firestore/lib/src/write_batch.dart | 3 ++- .../lib/src/transaction.dart | 3 --- .../lib/src/transaction_platform_interface.dart | 3 +++ .../cloud_firestore_web/lib/firestore_web.dart | 1 + .../cloud_firestore_web/lib/transaction_web.dart | 5 +++++ 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index 50de77242cf5..ca5a906a8067 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -13,7 +13,7 @@ class Transaction { Transaction._(this._delegate, this._firestore); - platform.Transaction _delegate; + platform.TransactionPlatform _delegate; // ignore: unused_element Future _finish() => _delegate.finish(); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index 9a568fa024fa..fa42f63080a0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -12,7 +12,8 @@ part of cloud_firestore; /// nor can it be committed again. class WriteBatch { - final platform.WriteBatch _delegate; + final platform.WriteBatchPlatform _delegate; + WriteBatch._(this._delegate); Future commit() => _delegate.commit(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart index 984d82b8e94b..c4eb600a8c2a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart @@ -21,9 +21,6 @@ class Transaction extends TransactionPlatform { : FirestorePlatform.instanceFor( app: FirebaseApp(name: appName))); - /// executes all the pending operations on the transaction - Future finish() => Future.wait(_pendingResults); - @override Future _get(DocumentReference documentReference) async { final Map result = await MethodChannelFirestore.channel diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart index 6ef0500f17da..33a11ae44030 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart @@ -21,6 +21,9 @@ abstract class TransactionPlatform { FirestorePlatform firestore; List> _pendingResults = >[]; + /// executes all the pending operations on the transaction + Future finish() => Future.wait(_pendingResults); + /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReference documentReference) { final Future result = _get(documentReference); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 4c2c25eba540..1b26a6f7d2dc 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,6 +4,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; import 'package:js/js_util.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 85db4181ab04..7cb905cbaf33 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -43,4 +43,9 @@ class TransactionWeb implements TransactionPlatform { (documentReference as DocumentReferenceWeb).delegate, data: CodecUtility.encodeMapData(data)); } + + @override + Future finish() { + return Future.value(); + } } From 5bcaa826cfb6dde28e74f3dd446197bae1fcbd13 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 17 Jan 2020 21:11:32 +0000 Subject: [PATCH 100/144] removed material import from firestore_web --- .../cloud_firestore/cloud_firestore_web/lib/firestore_web.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 1b26a6f7d2dc..4c2c25eba540 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -4,7 +4,6 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:firebase/firestore.dart' as web; import 'package:js/js_util.dart'; From 09aa7ff0b9e6506c1692531fab95c38cf42c59ca Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 17 Jan 2020 21:23:38 +0000 Subject: [PATCH 101/144] Fixed documentation comments --- .../cloud_firestore/lib/src/firestore.dart | 2 +- .../lib/cloud_firestore_platform_interface.dart | 14 +++++++------- .../lib/src/blob.dart | 6 +++--- .../cloud_firestore_web/lib/firestore_web.dart | 5 +++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 164816103139..a5a27eeb59b3 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -28,7 +28,7 @@ class Firestore { /// Gets the instance of Firestore for the default Firebase app. static Firestore get instance => Firestore(); - /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. + /// The [FirebaseApp] instance to which this [Firestore] belongs. /// /// If null, the default [FirebaseApp] is used. FirebaseApp get app => _delegate.app; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index dc52a12f28e1..ce700bf93baf 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -58,10 +58,10 @@ abstract class FirestorePlatform extends PlatformInterface { return FirestorePlatform.instance.withApp(app); } - /// Returns the current default [FirestorePlatform] instance. + /// The current default [FirestorePlatform] instance. /// /// It will always default to [MethodChannelFirestore] - /// if no web implementation was provided + /// if no web implementation was provided. static FirestorePlatform get instance { if (_instance == null) { _instance = MethodChannelFirestore(); @@ -111,18 +111,18 @@ abstract class FirestorePlatform extends PlatformInterface { throw UnimplementedError('batch() is not implemented'); } - /// Executes the given TransactionHandler and then attempts to commit the + /// Executes the given [TransactionHandler] and then attempts to commit the /// changes applied within an atomic transaction. /// - /// In the TransactionHandler, a set of reads and writes can be performed - /// atomically using the Transaction object passed to the TransactionHandler. - /// After the TransactionHandler is run, Firestore will attempt to apply the + /// In the [TransactionHandler], a set of reads and writes can be performed + /// atomically using the [Transaction] object passed to the [TransactionHandler]. + /// After the [TransactionHandler] is run, Firestore will attempt to apply the /// changes to the server. If any of the data read has been modified outside /// of this transaction since being read, then the transaction will be /// retried by executing the updateBlock again. If the transaction still /// fails after 5 retries, then the transaction will fail. /// - /// The TransactionHandler may be executed multiple times, it should be able + /// The [TransactionHandler] may be executed multiple times, it should be able /// to handle multiple executions. /// /// Data accessed with the transaction will not reflect local changes that diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index d66aaf2eb7ee..def15e443561 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -1,11 +1,11 @@ part of cloud_firestore_platform_interface; -/// Represents binary data stored in [Uint8List] +/// Represents binary data stored in [Uint8List]. class Blob { - /// Create a [Blob] + /// Create a blob. const Blob(this.bytes); - /// Blob Data bytes + /// The bytes that are contained in this blob. final Uint8List bytes; @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 4c2c25eba540..552790ce03f2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -36,7 +36,6 @@ class FirestoreWeb extends FirestorePlatform { /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { FirestorePlatform.instance = FirestoreWeb(); - FieldValueFactory.instance = FieldValueFactoryWeb(); } /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance @@ -44,7 +43,9 @@ class FirestoreWeb extends FirestorePlatform { FirestoreWeb({FirebaseApp app}) : webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), - super(app: app ?? FirebaseApp.instance); + super(app: app ?? FirebaseApp.instance) { + FieldValueFactory.instance = FieldValueFactoryWeb(); + } @override FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); From b09cd242d1479d47e84b31265b6722f6ff35b95c Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 17 Jan 2020 21:30:08 +0000 Subject: [PATCH 102/144] Added comment on the purpose of lazy init of Firestore delegate --- .../cloud_firestore/cloud_firestore/lib/src/firestore.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index a5a27eeb59b3..1e7b0f0052e3 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -8,6 +8,9 @@ part of cloud_firestore; /// /// You can get an instance by calling [Firestore.instance]. class Firestore { + // Cached and lazily loaded instance of [FirestorePlatform] to avoid + // creating a [MethodChannelFirestore] when not needed or creating an + // instance with the default app before a user specifies an app. platform.FirestorePlatform _delegatePackingProperty; platform.FirestorePlatform get _delegate { From 7428da20e3875c88514f288fc2aad77436b48670 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 27 Jan 2020 14:31:00 -0800 Subject: [PATCH 103/144] Separate Platform Interface source from Method Channel. --- .../lib/{src => }/method_channel_firestore.dart | 0 .../{ => method_channel}/method_channel_collection_reference.dart | 0 .../src/{ => method_channel}/method_channel_document_change.dart | 0 .../{ => method_channel}/method_channel_document_reference.dart | 0 .../{ => method_channel}/method_channel_field_value_factory.dart | 0 .../lib/src/{ => method_channel}/method_channel_query.dart | 0 .../src/{ => method_channel}/method_channel_query_snapshot.dart | 0 .../lib/src/{ => method_channel}/transaction.dart | 0 .../lib/src/{ => method_channel}/write_batch.dart | 0 .../{ => platform_interface}/transaction_platform_interface.dart | 0 .../{ => platform_interface}/write_batch_platform_interface.dart | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/{src => }/method_channel_firestore.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_collection_reference.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_document_change.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_document_reference.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_field_value_factory.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_query.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_query_snapshot.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/transaction.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/write_batch.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/transaction_platform_interface.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => platform_interface}/write_batch_platform_interface.dart (100%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_collection_reference.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_change.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_document_reference.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_field_value_factory.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_query_snapshot.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/transaction.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/transaction.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/write_batch.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/write_batch.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction_platform_interface.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/transaction_platform_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction_platform_interface.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch_platform_interface.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/write_batch_platform_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch_platform_interface.dart From 06242c84d429bbe3b8fa3fce0454006103a6844e Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 27 Jan 2020 14:31:44 -0800 Subject: [PATCH 104/144] Start fixing imports --- .../lib/method_channel_firestore.dart | 18 +++++++++++++++++- .../lib/src/utils/maps.dart | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart index 3e45b877a5d1..c82fa08c5b7e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart @@ -2,7 +2,23 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +library method_channel_firestore; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; +import 'dart:ui'; +import 'dart:math'; + +import 'package:collection/collection.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show required, visibleForTesting; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import './cloud_firestore_platform_interface.dart'; +import './src/utils/maps.dart'; /// The entry point for accessing a Firestore. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart new file mode 100644 index 000000000000..9c5d68a68827 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart @@ -0,0 +1,2 @@ +Map asStringKeyedMap(Map map) => + map?.cast(); From 52008c68a8dc040a6ba727dc984bc71d20f3ba8e Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 27 Jan 2020 14:49:03 -0800 Subject: [PATCH 105/144] Moved some more --- .../{transaction.dart => method_channel_transaction.dart} | 0 .../{write_batch.dart => method_channel_write_batch.dart} | 0 .../{transaction_platform_interface.dart => transaction.dart} | 0 .../{write_batch_platform_interface.dart => write_batch.dart} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/{transaction.dart => method_channel_transaction.dart} (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/{write_batch.dart => method_channel_write_batch.dart} (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/{transaction_platform_interface.dart => transaction.dart} (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/{write_batch_platform_interface.dart => write_batch.dart} (100%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/transaction.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/write_batch.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction_platform_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch_platform_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart From 5be6db86f72146dd517d1c9b05d6b5ae50da03ca Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 27 Jan 2020 15:36:52 -0800 Subject: [PATCH 106/144] Some more moving --- .../lib/{ => src}/method_channel_firestore.dart | 0 .../lib/src/{ => utils}/firestore_message_codec.dart | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/{ => src}/method_channel_firestore.dart (100%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => utils}/firestore_message_codec.dart (100%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/method_channel_firestore.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/firestore_message_codec.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart From 91ed554ca3f1ea4e98da8cfc6038ef866cb982b7 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 27 Jan 2020 15:51:52 -0800 Subject: [PATCH 107/144] Fix imports after moving files around. Interface should be identical as before. --- .../cloud_firestore_platform_interface.dart | 38 +++++++++++-------- .../lib/src/document_snapshot.dart | 3 -- .../lib/src/field_path.dart | 5 +-- .../method_channel_document_change.dart | 2 +- .../method_channel_document_reference.dart | 2 +- .../method_channel_query_snapshot.dart | 2 +- .../lib/src/method_channel_firestore.dart | 20 +--------- .../src/platform_interface/field_value.dart | 1 - .../lib/src/utils/auto_id_generator.dart | 3 +- .../src/utils/firestore_message_codec.dart | 12 +++--- .../lib/src/utils/maps.dart | 5 +++ 11 files changed, 42 insertions(+), 51 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index ce700bf93baf..86c5dc68849a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -4,7 +4,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui'; -import 'dart:math'; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -13,33 +12,42 @@ import 'package:flutter/services.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -part 'src/method_channel_firestore.dart'; -part 'src/blob.dart'; -part 'src/utils/auto_id_generator.dart'; -part 'src/method_channel_field_value_factory.dart'; +import 'src/utils/maps.dart'; +import 'src/utils/auto_id_generator.dart'; + +export 'src/utils/auto_id_generator.dart'; + +// Platform interface parts part 'src/platform_interface/field_value_factory.dart'; part 'src/platform_interface/collection_reference.dart'; -part 'src/method_channel_collection_reference.dart'; -part 'src/method_channel_document_change.dart'; part 'src/platform_interface/document_change.dart'; -part 'src/method_channel_document_reference.dart'; part 'src/platform_interface/document_reference_interface.dart'; +part 'src/platform_interface/transaction.dart'; +part 'src/platform_interface/write_batch.dart'; + +// Method channel parts +part 'src/method_channel_firestore.dart'; +part 'src/utils/firestore_message_codec.dart'; +part 'src/method_channel/method_channel_collection_reference.dart'; +part 'src/method_channel/method_channel_document_change.dart'; +part 'src/method_channel/method_channel_document_reference.dart'; +part 'src/method_channel/method_channel_field_value_factory.dart'; +part 'src/method_channel/method_channel_query_snapshot.dart'; +part 'src/method_channel/method_channel_query.dart'; +part 'src/method_channel/method_channel_transaction.dart'; +part 'src/method_channel/method_channel_write_batch.dart'; + +// Shared types +part 'src/blob.dart'; part 'src/document_snapshot.dart'; part 'src/field_path.dart'; part 'src/platform_interface/field_value.dart'; -part 'src/firestore_message_codec.dart'; part 'src/geo_point.dart'; -part 'src/method_channel_query.dart'; part 'src/platform_interface/query.dart'; part 'src/platform_interface/query_snapshot.dart'; -part 'src/method_channel_query_snapshot.dart'; part 'src/snapshot_metadata.dart'; part 'src/source.dart'; part 'src/timestamp.dart'; -part 'src/transaction.dart'; -part 'src/transaction_platform_interface.dart'; -part 'src/write_batch.dart'; -part 'src/write_batch_platform_interface.dart'; /// Defines an interface to work with [FirestorePlatform] on web and mobile abstract class FirestorePlatform extends PlatformInterface { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index 2036635858e6..952475f11784 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -37,6 +37,3 @@ class DocumentSnapshot { /// Returns `true` if the document exists. bool get exists => data != null; } - -Map _asStringKeyedMap(Map map) => - map?.cast(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index a611dc5d42f0..c2b6ec47b307 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -12,9 +12,8 @@ enum _FieldPathType { class FieldPath { const FieldPath._(this.type); - @visibleForTesting - // ignoring lint rule here as it's only visible for testing - // ignore: public_member_api_docs + /// The type of this FieldPath + /// (Used in the [FirestoreMessageCodec]) final _FieldPathType type; /// The path to the document id, which can be used in queries. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart index 9f92fc24bd1e..3b4442a5c9be 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart @@ -19,7 +19,7 @@ class MethodChannelDocumentChange extends DocumentChange { data['newIndex'], DocumentSnapshot( data['path'], - _asStringKeyedMap(data['document']), + asStringKeyedMap(data['document']), SnapshotMetadata(data['metadata']['hasPendingWrites'], data['metadata']['isFromCache']), firestore, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 339737011c78..0b99fbeb2002 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -51,7 +51,7 @@ class MethodChannelDocumentReference extends DocumentReference { ); return DocumentSnapshot( data['path'], - _asStringKeyedMap(data['data']), + asStringKeyedMap(data['data']), SnapshotMetadata(data['metadata']['hasPendingWrites'], data['metadata']['isFromCache']), firestore, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index 4ccc90a70367..d2770776be01 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -14,7 +14,7 @@ class MethodChannelQuerySnapshot extends QuerySnapshot { (int index) { return DocumentSnapshot( data['paths'][index], - _asStringKeyedMap(data['documents'][index]), + asStringKeyedMap(data['documents'][index]), SnapshotMetadata( data['metadatas'][index]['hasPendingWrites'], data['metadatas'][index]['isFromCache'], diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index c82fa08c5b7e..a6ea21464ad3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -2,23 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -library method_channel_firestore; - -import 'dart:async'; -import 'dart:convert'; -import 'dart:typed_data'; -import 'dart:ui'; -import 'dart:math'; - -import 'package:collection/collection.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:meta/meta.dart' show required, visibleForTesting; -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import './cloud_firestore_platform_interface.dart'; -import './src/utils/maps.dart'; +part of cloud_firestore_platform_interface; /// The entry point for accessing a Firestore. /// @@ -36,7 +20,7 @@ class MethodChannelFirestore extends FirestorePlatform { } else if (call.method == 'DocumentSnapshot') { final DocumentSnapshot snapshot = DocumentSnapshot( call.arguments['path'], - _asStringKeyedMap(call.arguments['data']), + asStringKeyedMap(call.arguments['data']), SnapshotMetadata(call.arguments['metadata']['hasPendingWrites'], call.arguments['metadata']['isFromCache']), this, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index c012cfac6c40..3416b8ff0392 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -21,7 +21,6 @@ abstract class FieldValueInterface { class FieldValue implements FieldValueInterface { /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValue] - @visibleForTesting static Map serverDelegates(Map data) { if (data == null) { return null; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart index 21485851c177..b6a1e13f463f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart @@ -1,8 +1,7 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; +import 'dart:math'; /// Utility class for generating Firebase child node keys. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart index 8bb6b39dc2ed..a26b3c472eea 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart @@ -106,20 +106,20 @@ class FirestoreMessageCodec extends StandardMessageCodec { return Blob(bytes); case _kArrayUnion: final List value = readValue(buffer); - return FieldValueFactory._instance.arrayUnion(value); + return FieldValueFactory.instance.arrayUnion(value); case _kArrayRemove: final List value = readValue(buffer); - return FieldValueFactory._instance.arrayRemove(value); + return FieldValueFactory.instance.arrayRemove(value); case _kDelete: - return FieldValueFactory._instance.delete(); + return FieldValueFactory.instance.delete(); case _kServerTimestamp: - return FieldValueFactory._instance.serverTimestamp(); + return FieldValueFactory.instance.serverTimestamp(); case _kIncrementDouble: final double value = readValue(buffer); - return FieldValueFactory._instance.increment(value); + return FieldValueFactory.instance.increment(value); case _kIncrementInteger: final int value = readValue(buffer); - return FieldValueFactory._instance.increment(value); + return FieldValueFactory.instance.increment(value); case _kDocumentId: return FieldPath.documentId; default: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart index 9c5d68a68827..038c74633892 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart @@ -1,2 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// Casts a Map to Map Map asStringKeyedMap(Map map) => map?.cast(); From 3c207c18a203d6b9c52c8c9b4eb282c4f5b15451 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Wed, 29 Jan 2020 13:06:39 -0800 Subject: [PATCH 108/144] Make all platform_interface classes names consistent. Query -> QueryPlatform QuerySnapshot -> QuerySnapshotPlatform FieldValue -> FieldValuePlatform FieldValueFactory -> FieldValueFactoryPlatform Rename document_reference_interface.dart -> document_reference.dart DocumentReference -> DocumentReferencePlatform DocumentChange -> DocumentChangePlatform CollectionReference -> CollectionReferencePlatform --- .../lib/src/collection_reference.dart | 2 +- .../lib/src/document_change.dart | 2 +- .../lib/src/document_reference.dart | 2 +- .../cloud_firestore/lib/src/field_value.dart | 10 +-- .../cloud_firestore/lib/src/query.dart | 2 +- .../lib/src/query_snapshot.dart | 2 +- .../lib/src/utils/codec_utility.dart | 2 +- .../cloud_firestore_platform_interface.dart | 16 ++--- .../lib/src/document_snapshot.dart | 2 +- .../method_channel_collection_reference.dart | 12 ++-- .../method_channel_document_change.dart | 2 +- .../method_channel_document_reference.dart | 10 +-- .../method_channel_field_value_factory.dart | 24 +++---- .../method_channel/method_channel_query.dart | 32 ++++----- .../method_channel_query_snapshot.dart | 4 +- .../method_channel_transaction.dart | 12 ++-- .../method_channel_write_batch.dart | 10 +-- .../lib/src/method_channel_firestore.dart | 12 ++-- .../collection_reference.dart | 16 ++--- .../platform_interface/document_change.dart | 12 ++-- ...interface.dart => document_reference.dart} | 28 ++++---- .../src/platform_interface/field_value.dart | 10 +-- .../field_value_factory.dart | 16 ++--- .../lib/src/platform_interface/query.dart | 64 ++++++++--------- .../platform_interface/query_snapshot.dart | 8 +-- .../src/platform_interface/transaction.dart | 18 ++--- .../src/platform_interface/write_batch.dart | 6 +- .../lib/src/snapshot_metadata.dart | 4 +- .../lib/src/source.dart | 2 +- .../src/utils/firestore_message_codec.dart | 14 ++-- .../test/document_reference_test.dart | 6 +- .../test/field_value_test.dart | 6 +- .../method_channel_cloud_firestore_test.dart | 70 +++++++++---------- .../method_channel_document_reference.dart | 4 +- .../test/query_test.dart | 4 +- .../test/transaction_test.dart | 2 +- .../lib/collection_reference_web.dart | 40 +++++------ .../lib/document_reference_web.dart | 4 +- .../lib/field_value_factory_web.dart | 4 +- .../lib/field_value_web.dart | 2 +- .../lib/firestore_web.dart | 16 ++--- .../cloud_firestore_web/lib/query_web.dart | 40 +++++------ .../lib/transaction_web.dart | 8 +-- .../lib/write_batch_web.dart | 6 +- 44 files changed, 280 insertions(+), 288 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/{document_reference_interface.dart => document_reference.dart} (74%) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart index d86237edb1f9..2f584667f930 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/collection_reference.dart @@ -8,7 +8,7 @@ part of cloud_firestore; /// document references, and querying for documents (using the methods /// inherited from [Query]). class CollectionReference extends Query { - final platform.CollectionReference _delegate; + final platform.CollectionReferencePlatform _delegate; CollectionReference._(this._delegate, Firestore firestore) : super._(_delegate, firestore); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index 058f1f270239..f3e9422e7891 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -23,7 +23,7 @@ enum DocumentChangeType { /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). class DocumentChange { - final platform.DocumentChange _delegate; + final platform.DocumentChangePlatform _delegate; final Firestore _firestore; DocumentChange._(this._delegate, this._firestore); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 1ebc94483443..5c2bfe547cbe 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -11,7 +11,7 @@ part of cloud_firestore; /// A [DocumentReference] can also be used to create a [CollectionReference] /// to a subcollection. class DocumentReference { - platform.DocumentReference _delegate; + platform.DocumentReferencePlatform _delegate; /// The Firestore instance associated with this document reference final Firestore firestore; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 8b35597e7bf5..1a522e51ec59 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -28,7 +28,7 @@ class FieldValue implements platform.FieldValueInterface { /// will be overwritten with an array containing exactly the specified /// elements. static FieldValue arrayUnion(List elements) => - FieldValue._(platform.FieldValueFactory.instance.arrayUnion(elements)); + FieldValue._(platform.FieldValueFactoryPlatform.instance.arrayUnion(elements)); /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -37,19 +37,19 @@ class FieldValue implements platform.FieldValueInterface { /// If the field being modified is not already an array it will be overwritten /// with an empty array. static FieldValue arrayRemove(List elements) => - FieldValue._(platform.FieldValueFactory.instance.arrayRemove(elements)); + FieldValue._(platform.FieldValueFactoryPlatform.instance.arrayRemove(elements)); /// Returns a sentinel for use with update() to mark a field for deletion. static FieldValue delete() => - FieldValue._(platform.FieldValueFactory.instance.delete()); + FieldValue._(platform.FieldValueFactoryPlatform.instance.delete()); /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. static FieldValue serverTimestamp() => - FieldValue._(platform.FieldValueFactory.instance.serverTimestamp()); + FieldValue._(platform.FieldValueFactoryPlatform.instance.serverTimestamp()); /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. static FieldValue increment(num value) => - FieldValue._(platform.FieldValueFactory.instance.increment(value)); + FieldValue._(platform.FieldValueFactoryPlatform.instance.increment(value)); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index a4be74091c40..8a38eb1aa5de 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -6,7 +6,7 @@ part of cloud_firestore; /// Represents a query over the data at a particular location. class Query { - final platform.Query _delegate; + final platform.QueryPlatform _delegate; /// The Firestore instance associated with this query final Firestore firestore; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 9226ed5c810c..2a5100c0575a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -6,7 +6,7 @@ part of cloud_firestore; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshot { - final platform.QuerySnapshot _delegate; + final platform.QuerySnapshotPlatform _delegate; final Firestore _firestore; QuerySnapshot._(this._delegate, this._firestore); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index 44b9e4cc0e63..ca56976604d0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -50,7 +50,7 @@ class _CodecUtility { } static dynamic valueDecode(dynamic value, Firestore firestore) { - if (value is platform.DocumentReference) { + if (value is platform.DocumentReferencePlatform) { return DocumentReference._(value, firestore); } else if (value is List) { return replaceDelegatesWithValueInArray(value, firestore); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 86c5dc68849a..55b9b1a227e2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -21,7 +21,7 @@ export 'src/utils/auto_id_generator.dart'; part 'src/platform_interface/field_value_factory.dart'; part 'src/platform_interface/collection_reference.dart'; part 'src/platform_interface/document_change.dart'; -part 'src/platform_interface/document_reference_interface.dart'; +part 'src/platform_interface/document_reference.dart'; part 'src/platform_interface/transaction.dart'; part 'src/platform_interface/write_batch.dart'; @@ -95,18 +95,18 @@ abstract class FirestorePlatform extends PlatformInterface { throw UnimplementedError("appName() not implemented"); } - /// Gets a [CollectionReference] for the specified Firestore path. - CollectionReference collection(String path) { + /// Gets a [CollectionReferencePlatform] for the specified Firestore path. + CollectionReferencePlatform collection(String path) { throw UnimplementedError('collection() is not implemented'); } - /// Gets a [Query] for the specified collection group. - Query collectionGroup(String path) { + /// Gets a [QueryPlatform] for the specified collection group. + QueryPlatform collectionGroup(String path) { throw UnimplementedError('collectionGroup() is not implemented'); } - /// Gets a [DocumentReference] for the specified Firestore path. - DocumentReference document(String path) { + /// Gets a [DocumentReferencePlatform] for the specified Firestore path. + DocumentReferencePlatform document(String path) { throw UnimplementedError('document() is not implemented'); } @@ -123,7 +123,7 @@ abstract class FirestorePlatform extends PlatformInterface { /// changes applied within an atomic transaction. /// /// In the [TransactionHandler], a set of reads and writes can be performed - /// atomically using the [Transaction] object passed to the [TransactionHandler]. + /// atomically using the [MethodChannelTransaction] object passed to the [TransactionHandler]. /// After the [TransactionHandler] is run, Firestore will attempt to apply the /// changes to the server. If any of the data read has been modified outside /// of this transaction since being read, then the transaction will be diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index 952475f11784..6b1d0e9d15d4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -19,7 +19,7 @@ class DocumentSnapshot { final FirestorePlatform firestore; /// The reference that produced this snapshot. - DocumentReference get reference => firestore.document(_path); + DocumentReferencePlatform get reference => firestore.document(_path); /// Contains all the data of this snapshot. final Map data; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index 5848d0ff2669..c72cedffc5c5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -6,9 +6,9 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods -/// inherited from [Query]). +/// inherited from [QueryPlatform]). class MethodChannelCollectionReference extends MethodChannelQuery - implements CollectionReference { + implements CollectionReferencePlatform { /// Create a [MethodChannelCollectionReference] from [pathComponents] MethodChannelCollectionReference( FirestorePlatform firestore, List pathComponents) @@ -18,7 +18,7 @@ class MethodChannelCollectionReference extends MethodChannelQuery String get id => pathComponents.isEmpty ? null : pathComponents.last; @override - DocumentReference parent() { + DocumentReferencePlatform parent() { if (pathComponents.length < 2) { return null; } @@ -29,7 +29,7 @@ class MethodChannelCollectionReference extends MethodChannelQuery } @override - DocumentReference document([String path]) { + DocumentReferencePlatform document([String path]) { List childPath; if (path == null) { final String key = AutoIdGenerator.autoId(); @@ -41,8 +41,8 @@ class MethodChannelCollectionReference extends MethodChannelQuery } @override - Future add(Map data) async { - final DocumentReference newDocument = document(); + Future add(Map data) async { + final DocumentReferencePlatform newDocument = document(); await newDocument.setData(data); return newDocument; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart index 3b4442a5c9be..ca17721f70db 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart @@ -8,7 +8,7 @@ part of cloud_firestore_platform_interface; /// /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). -class MethodChannelDocumentChange extends DocumentChange { +class MethodChannelDocumentChange extends DocumentChangePlatform { /// Create instance of [MethodChannelDocumentChange] using [data] MethodChannelDocumentChange( Map data, FirestorePlatform firestore) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 0b99fbeb2002..e80f8b75022d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -4,10 +4,10 @@ part of cloud_firestore_platform_interface; -/// A [MethodChannelDocumentReference] is an implementation of [DocumentReference] +/// A [MethodChannelDocumentReference] is an implementation of [DocumentReferencePlatform] /// that uses [MethodChannel] to communicate with Firebase plugins -class MethodChannelDocumentReference extends DocumentReference { - /// Creates a [DocumentReference] that is implemented using [MethodChannel]. +class MethodChannelDocumentReference extends DocumentReferencePlatform { + /// Creates a [DocumentReferencePlatform] that is implemented using [MethodChannel]. MethodChannelDocumentReference( FirestorePlatform firestore, List pathComponents) : assert(firestore != null), @@ -20,7 +20,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': FieldValue.serverDelegates(data), + 'data': FieldValuePlatform.serverDelegates(data), 'options': {'merge': merge}, }, ); @@ -33,7 +33,7 @@ class MethodChannelDocumentReference extends DocumentReference { { 'app': firestore.appName(), 'path': path, - 'data': FieldValue.serverDelegates(data), + 'data': FieldValuePlatform.serverDelegates(data), }, ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index e056e5f5d501..792479e61e9a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -1,33 +1,33 @@ part of cloud_firestore_platform_interface; -/// An implementation of [FieldValueFactory] that is suitable to be used +/// An implementation of [FieldValueFactoryPlatform] that is suitable to be used /// on mobile where communication relies on [MethodChannel] -class MethodChannelFieldValueFactory implements FieldValueFactory { +class MethodChannelFieldValueFactory implements FieldValueFactoryPlatform { @override - FieldValue arrayRemove(List elements) => - FieldValue._(FieldValueType.arrayRemove, elements); + FieldValuePlatform arrayRemove(List elements) => + FieldValuePlatform._(FieldValueType.arrayRemove, elements); @override - FieldValue arrayUnion(List elements) => - FieldValue._(FieldValueType.arrayUnion, elements); + FieldValuePlatform arrayUnion(List elements) => + FieldValuePlatform._(FieldValueType.arrayUnion, elements); @override - FieldValue delete() => FieldValue._(FieldValueType.delete, null); + FieldValuePlatform delete() => FieldValuePlatform._(FieldValueType.delete, null); @override - FieldValue increment(num value) { + FieldValuePlatform increment(num value) { // It is a compile-time error for any type other than `int` or `double` to // attempt to extend or implement `num`. assert(value is int || value is double); if (value is double) { - return FieldValue._(FieldValueType.incrementDouble, value); + return FieldValuePlatform._(FieldValueType.incrementDouble, value); } else if (value is int) { - return FieldValue._(FieldValueType.incrementInteger, value); + return FieldValuePlatform._(FieldValueType.incrementInteger, value); } return null; } @override - FieldValue serverTimestamp() => - FieldValue._(FieldValueType.serverTimestamp, null); + FieldValuePlatform serverTimestamp() => + FieldValuePlatform._(FieldValueType.serverTimestamp, null); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index b2bbcec63f36..dbb992d5b1fa 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -5,7 +5,7 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -class MethodChannelQuery extends Query { +class MethodChannelQuery extends QueryPlatform { /// Create a [MethodChannelQuery] from [pathComponents] MethodChannelQuery( {@required FirestorePlatform firestore, @@ -19,7 +19,7 @@ class MethodChannelQuery extends Query { parameters: parameters, ); - Query _copyWithParameters(Map parameters) { + QueryPlatform _copyWithParameters(Map parameters) { return MethodChannelQuery( firestore: firestore, isCollectionGroup: isCollectionGroup, @@ -32,13 +32,13 @@ class MethodChannelQuery extends Query { // TODO(jackson): Reduce code duplication with [DocumentReference] @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({bool includeMetadataChanges = false}) { assert(includeMetadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. - StreamController controller; // ignore: close_sinks - controller = StreamController.broadcast( + StreamController controller; // ignore: close_sinks + controller = StreamController.broadcast( onListen: () { _handle = MethodChannelFirestore.channel.invokeMethod( 'Query#addSnapshotListener', @@ -68,7 +68,7 @@ class MethodChannelQuery extends Query { } /// Fetch the documents for this query - Future getDocuments( + Future getDocuments( {Source source = Source.serverAndCache}) async { assert(source != null); final Map data = @@ -92,7 +92,7 @@ class MethodChannelQuery extends Query { }); @override - Query where(field, + QueryPlatform where(field, {isEqualTo, isLessThan, isLessThanOrEqualTo, @@ -147,7 +147,7 @@ class MethodChannelQuery extends Query { } @override - Query orderBy(field, {bool descending = false}) { + QueryPlatform orderBy(field, {bool descending = false}) { assert(field != null && descending != null); assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); @@ -176,7 +176,7 @@ class MethodChannelQuery extends Query { } @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -198,7 +198,7 @@ class MethodChannelQuery extends Query { } @override - Query startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -220,7 +220,7 @@ class MethodChannelQuery extends Query { } @override - Query startAfter(List values) { + QueryPlatform startAfter(List values) { assert(values != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -230,7 +230,7 @@ class MethodChannelQuery extends Query { } @override - Query startAt(List values) { + QueryPlatform startAt(List values) { assert(values != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -240,7 +240,7 @@ class MethodChannelQuery extends Query { } @override - Query endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); @@ -263,7 +263,7 @@ class MethodChannelQuery extends Query { } @override - Query endAt(List values) { + QueryPlatform endAt(List values) { assert(values != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); @@ -273,7 +273,7 @@ class MethodChannelQuery extends Query { } @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); @@ -295,7 +295,7 @@ class MethodChannelQuery extends Query { } @override - Query endBefore(List values) { + QueryPlatform endBefore(List values) { assert(values != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index d2770776be01..f41430c4d140 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -5,7 +5,7 @@ part of cloud_firestore_platform_interface; /// Contains zero or more [DocumentSnapshot] objects. -class MethodChannelQuerySnapshot extends QuerySnapshot { +class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { /// Creates a [MethodChannelQuerySnapshot] from the given [data] MethodChannelQuerySnapshot( Map data, FirestorePlatform firestore) @@ -22,7 +22,7 @@ class MethodChannelQuerySnapshot extends QuerySnapshot { firestore, ); }), - List.generate(data['documentChanges'].length, + List.generate(data['documentChanges'].length, (int index) { return MethodChannelDocumentChange( data['documentChanges'][index], diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index c4eb600a8c2a..b9db5efa338d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -22,7 +22,7 @@ class Transaction extends TransactionPlatform { app: FirebaseApp(name: appName))); @override - Future _get(DocumentReference documentReference) async { + Future _get(DocumentReferencePlatform documentReference) async { final Map result = await MethodChannelFirestore.channel .invokeMapMethod('Transaction#get', { 'app': firestore.appName(), @@ -42,7 +42,7 @@ class Transaction extends TransactionPlatform { } @override - Future _delete(DocumentReference documentReference) async { + Future _delete(DocumentReferencePlatform documentReference) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#delete', { 'app': firestore.appName(), @@ -53,25 +53,25 @@ class Transaction extends TransactionPlatform { @override Future _update( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#update', { 'app': firestore.appName(), 'transactionId': _transactionId, 'path': documentReference.path, - 'data': FieldValue.serverDelegates(data), + 'data': FieldValuePlatform.serverDelegates(data), }); } @override Future _set( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#set', { 'app': firestore.appName(), 'transactionId': _transactionId, 'path': documentReference.path, - 'data': FieldValue.serverDelegates(data), + 'data': FieldValuePlatform.serverDelegates(data), }); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index 2b3da0101632..ca205b5a91bd 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -33,7 +33,7 @@ class WriteBatch extends WriteBatchPlatform { } @override - void delete(DocumentReference document) { + void delete(DocumentReferencePlatform document) { _assertNotCommitted(); _handle.then((dynamic handle) { @@ -51,7 +51,7 @@ class WriteBatch extends WriteBatchPlatform { } @override - void setData(DocumentReference document, Map data, + void setData(DocumentReferencePlatform document, Map data, {bool merge = false}) { _assertNotCommitted(); @@ -63,7 +63,7 @@ class WriteBatch extends WriteBatchPlatform { 'app': _firestore.appName(), 'handle': handle, 'path': document.path, - 'data': FieldValue.serverDelegates(data), + 'data': FieldValuePlatform.serverDelegates(data), 'options': {'merge': merge}, }, ), @@ -72,7 +72,7 @@ class WriteBatch extends WriteBatchPlatform { } @override - void updateData(DocumentReference document, Map data) { + void updateData(DocumentReferencePlatform document, Map data) { _assertNotCommitted(); _handle.then((dynamic handle) { @@ -83,7 +83,7 @@ class WriteBatch extends WriteBatchPlatform { 'app': _firestore.appName(), 'handle': handle, 'path': document.path, - 'data': FieldValue.serverDelegates(data) + 'data': FieldValuePlatform.serverDelegates(data) }, ), ); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index a6ea21464ad3..58d7ca09d886 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -14,7 +14,7 @@ class MethodChannelFirestore extends FirestorePlatform { if (_initialized) return; channel.setMethodCallHandler((MethodCall call) async { if (call.method == 'QuerySnapshot') { - final QuerySnapshot snapshot = + final QuerySnapshotPlatform snapshot = MethodChannelQuerySnapshot(call.arguments, this); _queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { @@ -51,8 +51,8 @@ class MethodChannelFirestore extends FirestorePlatform { StandardMethodCodec(FirestoreMessageCodec()), ); - static final Map> _queryObservers = - >{}; + static final Map> _queryObservers = + >{}; static final Map> _documentObservers = >{}; @@ -66,13 +66,13 @@ class MethodChannelFirestore extends FirestorePlatform { MethodChannelFirestore(app: app); @override - CollectionReference collection(String path) { + CollectionReferencePlatform collection(String path) { assert(path != null); return MethodChannelCollectionReference(this, path.split('/')); } @override - Query collectionGroup(String path) { + QueryPlatform collectionGroup(String path) { assert(path != null); assert(!path.contains("/"), "Collection IDs must not contain '/'."); return MethodChannelQuery( @@ -83,7 +83,7 @@ class MethodChannelFirestore extends FirestorePlatform { } @override - DocumentReference document(String path) { + DocumentReferencePlatform document(String path) { assert(path != null); return MethodChannelDocumentReference(this, path.split('/')); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index b184134e2a34..e8479d2e7e95 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -6,19 +6,19 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods -/// inherited from [Query]). -abstract class CollectionReference extends Query { - /// Create a [CollectionReference] using [pathComponents] - CollectionReference(FirestorePlatform firestore, List pathComponents) +/// inherited from [QueryPlatform]). +abstract class CollectionReferencePlatform extends QueryPlatform { + /// Create a [CollectionReferencePlatform] using [pathComponents] + CollectionReferencePlatform(FirestorePlatform firestore, List pathComponents) : super(firestore: firestore, pathComponents: pathComponents); /// Identifier of the referenced collection. String get id => pathComponents.isEmpty ? null : pathComponents.last; - /// For subcollections, parent returns the containing [DocumentReference]. + /// For subcollections, parent returns the containing [DocumentReferencePlatform]. /// /// For root collections, `null` is returned. - DocumentReference parent() { + DocumentReferencePlatform parent() { throw UnimplementedError("parent() is not implemented"); } @@ -28,7 +28,7 @@ abstract class CollectionReference extends Query { /// /// The unique key generated is prefixed with a client-generated timestamp /// so that the resulting list will be chronologically-sorted. - DocumentReference document([String path]) { + DocumentReferencePlatform document([String path]) { throw UnimplementedError("document() is not implemented"); } @@ -37,7 +37,7 @@ abstract class CollectionReference extends Query { /// /// The unique key generated is prefixed with a client-generated timestamp /// so that the resulting list will be chronologically-sorted. - Future add(Map data) async { + Future add(Map data) async { throw UnimplementedError("add() is not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index eb143207aa25..cc08d7d63ccb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -22,23 +22,23 @@ enum DocumentChangeType { /// /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). -class DocumentChange { - /// Create a [DocumentChange] - DocumentChange(this.type, this.oldIndex, this.newIndex, this.document); +class DocumentChangePlatform { + /// Create a [DocumentChangePlatform] + DocumentChangePlatform(this.type, this.oldIndex, this.newIndex, this.document); /// The type of change that occurred (added, modified, or removed). final DocumentChangeType type; /// The index of the changed document in the result set immediately prior to - /// this [DocumentChange] (i.e. supposing that all prior DocumentChange objects + /// this [DocumentChangePlatform] (i.e. supposing that all prior DocumentChange objects /// have been applied). /// /// -1 for [DocumentChangeType.added] events. final int oldIndex; /// The index of the changed document in the result set immediately after this - /// DocumentChange (i.e. supposing that all prior [DocumentChange] objects - /// and the current [DocumentChange] object have been applied). + /// DocumentChange (i.e. supposing that all prior [DocumentChangePlatform] objects + /// and the current [DocumentChangePlatform] object have been applied). /// /// -1 for [DocumentChangeType.removed] events. final int newIndex; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart similarity index 74% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 558d42544e11..da067a6c6c34 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -1,14 +1,14 @@ part of cloud_firestore_platform_interface; -/// A [DocumentReference] refers to a document location in a Firestore database +/// A [DocumentReferencePlatform] refers to a document location in a Firestore database /// and can be used to write, read, or listen to the location. /// /// The document at the referenced location may or may not exist. -/// A [DocumentReference] can also be used to create a [CollectionReference] +/// A [DocumentReferencePlatform] can also be used to create a [CollectionReferencePlatform] /// to a subcollection. -abstract class DocumentReference { - /// Create instance of [DocumentReference] - DocumentReference(this.firestore, this._pathComponents); +abstract class DocumentReferencePlatform { + /// Create instance of [DocumentReferencePlatform] + DocumentReferencePlatform(this.firestore, this._pathComponents); /// The Firestore instance associated with this document reference final FirestorePlatform firestore; @@ -16,13 +16,13 @@ abstract class DocumentReference { @override bool operator ==(dynamic o) => - o is DocumentReference && o.firestore == firestore && o.path == path; + o is DocumentReferencePlatform && o.firestore == firestore && o.path == path; @override int get hashCode => hashList(_pathComponents); - /// Parent returns the containing [CollectionReference]. - CollectionReference parent() { + /// Parent returns the containing [CollectionReferencePlatform]. + CollectionReferencePlatform parent() { final parentPathComponents = List.from(_pathComponents) ..removeLast(); return firestore.collection( @@ -36,7 +36,7 @@ abstract class DocumentReference { /// This document's given or generated ID in the collection. String get documentID => _pathComponents.last; - /// Writes to the document referred to by this [DocumentReference]. + /// Writes to the document referred to by this [DocumentReferencePlatform]. /// /// If the document does not yet exist, it will be created. /// @@ -46,31 +46,31 @@ abstract class DocumentReference { throw UnimplementedError("setData() is not implemented"); } - /// Updates fields in the document referred to by this [DocumentReference]. + /// Updates fields in the document referred to by this [DocumentReferencePlatform]. /// /// Values in [data] may be of any supported Firestore type as well as - /// special sentinel [FieldValue] type. + /// special sentinel [FieldValuePlatform] type. /// /// If no document exists yet, the update will fail. Future updateData(Map data) { throw UnimplementedError("updateData() is not implemented"); } - /// Reads the document referenced by this [DocumentReference]. + /// Reads the document referenced by this [DocumentReferencePlatform]. /// /// If no document exists, the read will return null. Future get({Source source = Source.serverAndCache}) async { throw UnimplementedError("get() is not implemented"); } - /// Deletes the document referred to by this [DocumentReference]. + /// Deletes the document referred to by this [DocumentReferencePlatform]. Future delete() { throw UnimplementedError("delete() is not implemented"); } /// Returns the reference of a collection contained inside of this /// document. - CollectionReference collection(String collectionPath) { + CollectionReferencePlatform collection(String collectionPath) { return firestore.collection('$path/$collectionPath'); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 3416b8ff0392..e07115d87a5e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -17,17 +17,17 @@ abstract class FieldValueInterface { dynamic get value; } -/// Mobile platform implementation for [FieldValueInterface] -class FieldValue implements FieldValueInterface { +/// Platform Interface of a FieldValue; implementation for [FieldValueInterface] +class FieldValuePlatform implements FieldValueInterface { /// Replaces items with type [FieldValueInterface] with implementation type - /// such as [FieldValue] + /// such as [FieldValuePlatform] static Map serverDelegates(Map data) { if (data == null) { return null; } Map output = Map.from(data); output.updateAll((key, value) { - if (value is FieldValueInterface && value.instance is FieldValue) { + if (value is FieldValueInterface && value.instance is FieldValuePlatform) { return value.instance; } else { return value; @@ -36,7 +36,7 @@ class FieldValue implements FieldValueInterface { return output; } - FieldValue._(this.type, this.value); + FieldValuePlatform._(this.type, this.value); @override FieldValueInterface get instance => this; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 6118a3770d23..819a13850df6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -22,17 +22,17 @@ enum FieldValueType { incrementInteger, } -/// An interface for a factory that is used to build [FieldValue] according to +/// An interface for a factory that is used to build [FieldValuePlatform] according to /// Platform (web or mobile) -abstract class FieldValueFactory { - /// Current instance of [FieldValueFactory] - static FieldValueFactory get instance => _instance; +abstract class FieldValueFactoryPlatform { + /// Current instance of [FieldValueFactoryPlatform] + static FieldValueFactoryPlatform get instance => _instance; - static FieldValueFactory _instance = MethodChannelFieldValueFactory(); + static FieldValueFactoryPlatform _instance = MethodChannelFieldValueFactory(); - /// Sets the default instance of [FieldValueFactory] which is used to build - /// [FieldValue] items - static set instance(FieldValueFactory instance) { + /// Sets the default instance of [FieldValueFactoryPlatform] which is used to build + /// [FieldValuePlatform] items + static set instance(FieldValueFactoryPlatform instance) { _instance = instance; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 0266c675a68a..be8a7f06ee05 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -5,9 +5,9 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -abstract class Query { - /// Create a [Query] instance - Query( +abstract class QueryPlatform { + /// Create a [QueryPlatform] instance + QueryPlatform( {@required this.firestore, @required List pathComponents, bool isCollectionGroup = false, @@ -25,43 +25,43 @@ abstract class Query { /// The Firestore instance associated with this query final FirestorePlatform firestore; - /// Represents the components of the path referenced by `this` [Query] + /// Represents the components of the path referenced by `this` [QueryPlatform] final List pathComponents; /// Map of the parameters used for filtering and sorting documents final Map parameters; - /// Indicates if `this` [Query] is for a collection group + /// Indicates if `this` [QueryPlatform] is for a collection group final bool isCollectionGroup; - /// Represents the path referenced by `this` [Query] + /// Represents the path referenced by `this` [QueryPlatform] String get path => pathComponents.join('/'); - Query _copyWithParameters(Map parameters) { + QueryPlatform _copyWithParameters(Map parameters) { throw UnimplementedError("copyWithParameters() is not implemented"); } - /// Builds a map of all the parameters used and appends the [Query.path] + /// Builds a map of all the parameters used and appends the [QueryPlatform.path] Map buildArguments() { throw UnimplementedError("buildArguments() is not imlpmented"); } /// Notifies of query results at this location - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({bool includeMetadataChanges = false}) { throw UnimplementedError("snapshots() is not implemented"); } /// Fetch the documents for this query - Future getDocuments( + Future getDocuments( {Source source = Source.serverAndCache}) async { throw UnimplementedError("getDocuments() is not implemented"); } /// Obtains a CollectionReference corresponding to this query's location. - CollectionReference reference() => + CollectionReferencePlatform reference() => firestore.collection(pathComponents.join("/")); - /// Creates and returns a new [Query] with additional filter on specified + /// Creates and returns a new [QueryPlatform] with additional filter on specified /// [field]. [field] refers to a field in a document. /// /// The [field] may be a [String] consisting of a single field name @@ -72,7 +72,7 @@ abstract class Query { /// /// Only documents satisfying provided condition are included in the result /// set. - Query where( + QueryPlatform where( dynamic field, { dynamic isEqualTo, dynamic isLessThan, @@ -87,7 +87,7 @@ abstract class Query { throw UnimplementedError("where() is not implemented"); } - /// Creates and returns a new [Query] that's additionally sorted by the specified + /// Creates and returns a new [QueryPlatform] that's additionally sorted by the specified /// [field]. /// The field may be a [String] representing a single field name or a [FieldPath]. /// @@ -97,11 +97,11 @@ abstract class Query { /// using [startAfterDocument], [startAtDocument], [endAfterDocument], /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. - Query orderBy(dynamic field, {bool descending = false}) { + QueryPlatform orderBy(dynamic field, {bool descending = false}) { throw UnimplementedError("orderBy() is not implemented"); } - /// Creates and returns a new [Query] that starts after the provided document + /// Creates and returns a new [QueryPlatform] that starts after the provided document /// (exclusive). The starting position is relative to the order of the query. /// The document must contain all of the fields provided in the orderBy of /// this query. @@ -115,11 +115,11 @@ abstract class Query { /// * [endAfterDocument] for a query that ends after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { throw UnimplementedError("startAfterDocument() is not implemented"); } - /// Creates and returns a new [Query] that starts at the provided document + /// Creates and returns a new [QueryPlatform] that starts at the provided document /// (inclusive). The starting position is relative to the order of the query. /// The document must contain all of the fields provided in the orderBy of /// this query. @@ -133,11 +133,11 @@ abstract class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { throw UnimplementedError("startAtDocument() is not implemented"); } - /// Takes a list of [values], creates and returns a new [Query] that starts + /// Takes a list of [values], creates and returns a new [QueryPlatform] that starts /// after the provided fields relative to the order of the query. /// /// The [values] must be in order of [orderBy] filters. @@ -145,11 +145,11 @@ abstract class Query { /// Cannot be used in combination with [startAt], [startAfterDocument], or /// [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAfter(List values) { + QueryPlatform startAfter(List values) { throw UnimplementedError("startAfter() is not implemented"); } - /// Takes a list of [values], creates and returns a new [Query] that starts at + /// Takes a list of [values], creates and returns a new [QueryPlatform] that starts at /// the provided fields relative to the order of the query. /// /// The [values] must be in order of [orderBy] filters. @@ -157,11 +157,11 @@ abstract class Query { /// Cannot be used in combination with [startAfter], [startAfterDocument], /// or [startAtDocument], but can be used in combination with [endAt], /// [endBefore], [endAtDocument] and [endBeforeDocument]. - Query startAt(List values) { + QueryPlatform startAt(List values) { throw UnimplementedError("startAt() is not implemented"); } - /// Creates and returns a new [Query] that ends at the provided document + /// Creates and returns a new [QueryPlatform] that ends at the provided document /// (inclusive). The end position is relative to the order of the query. /// The document must contain all of the fields provided in the orderBy of /// this query. @@ -175,11 +175,11 @@ abstract class Query { /// * [startAfterDocument] for a query that starts after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. - Query endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { throw UnimplementedError("endAtDocument() is not implemented"); } - /// Takes a list of [values], creates and returns a new [Query] that ends at the + /// Takes a list of [values], creates and returns a new [QueryPlatform] that ends at the /// provided fields relative to the order of the query. /// /// The [values] must be in order of [orderBy] filters. @@ -187,11 +187,11 @@ abstract class Query { /// Cannot be used in combination with [endBefore], [endBeforeDocument], or /// [endAtDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endAt(List values) { + QueryPlatform endAt(List values) { throw UnimplementedError("endAt() is not implemented"); } - /// Creates and returns a new [Query] that ends before the provided document + /// Creates and returns a new [QueryPlatform] that ends before the provided document /// (exclusive). The end position is relative to the order of the query. /// The document must contain all of the fields provided in the orderBy of /// this query. @@ -205,11 +205,11 @@ abstract class Query { /// * [startAfterDocument] for a query that starts after document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { throw UnimplementedError("endBeforeDocument() is not implemented"); } - /// Takes a list of [values], creates and returns a new [Query] that ends before + /// Takes a list of [values], creates and returns a new [QueryPlatform] that ends before /// the provided fields relative to the order of the query. /// /// The [values] must be in order of [orderBy] filters. @@ -217,13 +217,13 @@ abstract class Query { /// Cannot be used in combination with [endAt], [endBeforeDocument], or /// [endBeforeDocument], but can be used in combination with [startAt], /// [startAfter], [startAtDocument] and [startAfterDocument]. - Query endBefore(List values) { + QueryPlatform endBefore(List values) { throw UnimplementedError("endBefore() is not implemented"); } /// Creates and returns a new Query that's additionally limited to only return up /// to the specified number of documents. - Query limit(int length) { + QueryPlatform limit(int length) { assert(!parameters.containsKey('limit')); return _copyWithParameters({'limit': length}); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 48d7e767ce07..02c42343fe3c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -5,16 +5,16 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. -class QuerySnapshot { - /// Create a [QuerySnapshot] - QuerySnapshot(this.documents, this.documentChanges, this.metadata); +class QuerySnapshotPlatform { + /// Create a [QuerySnapshotPlatform] + QuerySnapshotPlatform(this.documents, this.documentChanges, this.metadata); /// Gets a list of all the documents included in this snapshot final List documents; /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. - final List documentChanges; + final List documentChanges; /// Metadata for the document final SnapshotMetadata metadata; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 33a11ae44030..1be366150351 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -25,13 +25,13 @@ abstract class TransactionPlatform { Future finish() => Future.wait(_pendingResults); /// Reads the document referenced by the provided DocumentReference. - Future get(DocumentReference documentReference) { + Future get(DocumentReferencePlatform documentReference) { final Future result = _get(documentReference); _pendingResults.add(result); return result; } - Future _get(DocumentReference documentReference) async { + Future _get(DocumentReferencePlatform documentReference) async { throw UnimplementedError("get() not implemented"); } @@ -39,13 +39,13 @@ abstract class TransactionPlatform { /// /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. - Future delete(DocumentReference documentReference) { + Future delete(DocumentReferencePlatform documentReference) { final Future result = _delete(documentReference); _pendingResults.add(result); return result; } - Future _delete(DocumentReference documentReference) async { + Future _delete(DocumentReferencePlatform documentReference) async { throw UnimplementedError("delete() not implemented"); } @@ -55,32 +55,32 @@ abstract class TransactionPlatform { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future update( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { final Future result = _update(documentReference, data); _pendingResults.add(result); return result; } Future _update( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { throw UnimplementedError("updated() not implemented"); } - /// Writes to the document referred to by the provided [DocumentReference]. + /// Writes to the document referred to by the provided [DocumentReferencePlatform]. /// If the document does not exist yet, it will be created. If you pass /// SetOptions, the provided data can be merged into the existing document. /// /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future set( - DocumentReference documentReference, Map data) { + DocumentReferencePlatform documentReference, Map data) { final Future result = _set(documentReference, data); _pendingResults.add(result); return result; } Future _set( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { throw UnimplementedError("set() not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index 4a7043800174..f6e565bc9b53 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -24,7 +24,7 @@ abstract class WriteBatchPlatform { } /// Deletes the document referred to by [document]. - void delete(DocumentReference document) { + void delete(DocumentReferencePlatform document) { throw UnimplementedError("commit() not implemented"); } @@ -34,7 +34,7 @@ abstract class WriteBatchPlatform { /// /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. - void setData(DocumentReference document, Map data, + void setData(DocumentReferencePlatform document, Map data, {bool merge = false}) { throw UnimplementedError("commit() not implemented"); } @@ -42,7 +42,7 @@ abstract class WriteBatchPlatform { /// Updates fields in the document referred to by [document]. /// /// If the document does not exist, the operation will fail. - void updateData(DocumentReference document, Map data) { + void updateData(DocumentReferencePlatform document, Map data) { throw UnimplementedError("commit() not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart index 8984e744d604..5a287bcf0c82 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart @@ -12,7 +12,7 @@ class SnapshotMetadata { /// Whether the snapshot contains the result of local writes that have not yet /// been committed to the backend. /// - /// If you called [DocumentReference.snapshots] or [Query.snapshots] with + /// If you called [DocumentReferencePlatform.snapshots] or [QueryPlatform.snapshots] with /// `includeMetadataChanges` parameter set to `true` you will receive another /// snapshot with `hasPendingWrites` equal to `false` once the writes have been /// committed to the backend. @@ -21,7 +21,7 @@ class SnapshotMetadata { /// Whether the snapshot was created from cached data rather than guaranteed /// up-to-date server data. /// - /// If you called [DocumentReference.snapshots] or [Query.snapshots] with + /// If you called [DocumentReferencePlatform.snapshots] or [QueryPlatform.snapshots] with /// `includeMetadataChanges` parameter set to `true` you will receive another /// snapshot with `isFomCache` equal to `false` once the client has received /// up-to-date data from the backend. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart index 764a02f4d21f..77364e23a024 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart @@ -20,7 +20,7 @@ enum Source { /// (implying that the returned value may be stale with respect to the value on the server). If /// there is no data in the cache to satisfy the [get()] or [getDocuments()] call, /// [DocumentReference.get()] will return an error and [Query.getDocuments()] will return an empty - /// [QuerySnapshot] with no documents. + /// [QuerySnapshotPlatform] with no documents. cache, } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart index a26b3c472eea..7f7add8b5af8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart @@ -54,7 +54,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putUint8(_kGeoPoint); buffer.putFloat64(value.latitude); buffer.putFloat64(value.longitude); - } else if (value is DocumentReference) { + } else if (value is DocumentReferencePlatform) { buffer.putUint8(_kDocumentReference); final List appName = utf8.encoder.convert(value.firestore.appName()); writeSize(buffer, appName.length); @@ -106,20 +106,20 @@ class FirestoreMessageCodec extends StandardMessageCodec { return Blob(bytes); case _kArrayUnion: final List value = readValue(buffer); - return FieldValueFactory.instance.arrayUnion(value); + return FieldValueFactoryPlatform.instance.arrayUnion(value); case _kArrayRemove: final List value = readValue(buffer); - return FieldValueFactory.instance.arrayRemove(value); + return FieldValueFactoryPlatform.instance.arrayRemove(value); case _kDelete: - return FieldValueFactory.instance.delete(); + return FieldValueFactoryPlatform.instance.delete(); case _kServerTimestamp: - return FieldValueFactory.instance.serverTimestamp(); + return FieldValueFactoryPlatform.instance.serverTimestamp(); case _kIncrementDouble: final double value = readValue(buffer); - return FieldValueFactory.instance.increment(value); + return FieldValueFactoryPlatform.instance.increment(value); case _kIncrementInteger: final int value = readValue(buffer); - return FieldValueFactory.instance.increment(value); + return FieldValueFactoryPlatform.instance.increment(value); case _kDocumentId: return FieldPath.documentId; default: diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart index 4b6d14b4e00f..db51ad4b7f86 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart @@ -4,19 +4,19 @@ import 'package:flutter_test/flutter_test.dart'; const _kCollectionId = "test"; const _kDocumentId = "document"; -class TestDocumentReference extends DocumentReference { +class TestDocumentReference extends DocumentReferencePlatform { TestDocumentReference._() : super(FirestorePlatform.instance, [_kCollectionId, _kDocumentId]); } void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$DocumentReference()", () { + group("$DocumentReferencePlatform()", () { test("Parent", () { final document = TestDocumentReference._(); final parent = document.parent(); final parentPath = parent.path; - expect(parent, isInstanceOf()); + expect(parent, isInstanceOf()); expect(parentPath, equals(_kCollectionId)); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart index 3e9106d2ada8..0dd1fc3f7f02 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -6,12 +6,12 @@ class MockFieldValue extends Mock implements FieldValueInterface {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$FieldValue()", () { + group("$FieldValuePlatform()", () { test("serverDelegates", () { - expect(FieldValue.serverDelegates(null), isNull); + expect(FieldValuePlatform.serverDelegates(null), isNull); final mockFieldValue = MockFieldValue(); - FieldValue.serverDelegates({"item": mockFieldValue}); + FieldValuePlatform.serverDelegates({"item": mockFieldValue}); verify(mockFieldValue.instance); }); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index c6a4b9e62ae8..ab4653ab6481 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -18,8 +18,8 @@ void main() { FirebaseApp app; MethodChannelFirestore firestore; final List log = []; - CollectionReference collectionReference; - Query collectionGroupQuery; + CollectionReferencePlatform collectionReference; + QueryPlatform collectionGroupQuery; Transaction transaction; const Map kMockDocumentSnapshotData = { '1': 2 @@ -218,7 +218,7 @@ void main() { }); test('get', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); final DocumentSnapshot snapshot = await transaction.get(documentReference); @@ -233,7 +233,7 @@ void main() { }); test('get notExists', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/notExists'); await transaction.get(documentReference); expect(log, [ @@ -246,7 +246,7 @@ void main() { }); test('delete', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); await transaction.delete(documentReference); expect(log, [ @@ -259,7 +259,7 @@ void main() { }); test('update', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); final DocumentSnapshot documentSnapshot = await documentReference.get(); final Map data = documentSnapshot.data; @@ -281,7 +281,7 @@ void main() { }); test('set', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); final DocumentSnapshot documentSnapshot = await documentReference.get(); final Map data = documentSnapshot.data; @@ -329,7 +329,7 @@ void main() { expect(collectionReference.id, equals('foo')); }); test('parent', () async { - final DocumentReference docRef = collectionReference.document('bar'); + final DocumentReferencePlatform docRef = collectionReference.document('bar'); expect(docRef.parent().id, equals('foo')); expect(collectionReference.parent(), isNull); }); @@ -337,7 +337,7 @@ void main() { expect(collectionReference.path, equals('foo')); }); test('listen', () async { - final QuerySnapshot snapshot = await collectionReference + final QuerySnapshotPlatform snapshot = await collectionReference .snapshots(includeMetadataChanges: true) .first; final DocumentSnapshot document = snapshot.documents[0]; @@ -367,11 +367,11 @@ void main() { ]); }); test('where', () async { - final StreamSubscription subscription = + final StreamSubscription subscription = collectionReference .where('createdAt', isLessThan: 100) .snapshots() - .listen((QuerySnapshot querySnapshot) {}); + .listen((QuerySnapshotPlatform querySnapshot) {}); subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( @@ -400,11 +400,11 @@ void main() { ); }); test('where in', () async { - final StreamSubscription subscription = + final StreamSubscription subscription = collectionReference .where('country', whereIn: ['USA', 'Japan']) .snapshots() - .listen((QuerySnapshot querySnapshot) {}); + .listen((QuerySnapshotPlatform querySnapshot) {}); subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( @@ -437,12 +437,12 @@ void main() { ); }); test('where array-contains-any', () async { - final StreamSubscription subscription = + final StreamSubscription subscription = collectionReference .where('regions', arrayContainsAny: ['west-coast', 'east-coast']) .snapshots() - .listen((QuerySnapshot querySnapshot) {}); + .listen((QuerySnapshotPlatform querySnapshot) {}); subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( @@ -475,11 +475,11 @@ void main() { ); }); test('where field isNull', () async { - final StreamSubscription subscription = + final StreamSubscription subscription = collectionReference .where('profile', isNull: true) .snapshots() - .listen((QuerySnapshot querySnapshot) {}); + .listen((QuerySnapshotPlatform querySnapshot) {}); subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( @@ -508,11 +508,11 @@ void main() { ); }); test('orderBy', () async { - final StreamSubscription subscription = + final StreamSubscription subscription = collectionReference .orderBy('createdAt') .snapshots() - .listen((QuerySnapshot querySnapshot) {}); + .listen((QuerySnapshotPlatform querySnapshot) {}); subscription.cancel(); // ignore: unawaited_futures await Future.delayed(Duration.zero); expect( @@ -691,12 +691,12 @@ void main() { } }); test('collection', () async { - final CollectionReference colRef = + final CollectionReferencePlatform colRef = collectionReference.document('bar').collection('baz'); expect(colRef.path, equals('foo/bar/baz')); }); test('parent', () async { - final CollectionReference colRef = + final CollectionReferencePlatform colRef = collectionReference.document('bar').collection('baz'); expect(colRef.parent().documentID, equals('bar')); }); @@ -704,7 +704,7 @@ void main() { group('Query', () { test('getDocumentsFromCollection', () async { - QuerySnapshot snapshot = + QuerySnapshotPlatform snapshot = await collectionReference.getDocuments(source: Source.server); expect(snapshot.metadata.hasPendingWrites, equals(kMockSnapshotMetadata['hasPendingWrites'])); @@ -876,7 +876,7 @@ void main() { ); }); test('getDocumentsFromCollectionGroup', () async { - QuerySnapshot snapshot = await collectionGroupQuery.getDocuments(); + QuerySnapshotPlatform snapshot = await collectionGroupQuery.getDocuments(); expect(snapshot.metadata.hasPendingWrites, equals(kMockSnapshotMetadata['hasPendingWrites'])); expect(snapshot.metadata.isFromCache, @@ -1092,7 +1092,7 @@ void main() { }, throwsAssertionError); // Cannot order by document id when paginating with documents. - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); final DocumentSnapshot snapshot = await documentReference.get(); expect(() { @@ -1103,10 +1103,10 @@ void main() { }, throwsAssertionError); }); test('document pagination FieldPath assertions', () async { - final DocumentReference documentReference = + final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); final DocumentSnapshot snapshot = await documentReference.get(); - final Query query = + final QueryPlatform query = firestore.collection('foo').orderBy(FieldPath.documentId); expect(() { @@ -1152,16 +1152,16 @@ void main() { test('encode and decode FieldValue', () { _checkEncodeDecode( - codec, FieldValueFactory.instance.arrayUnion([123])); + codec, FieldValueFactoryPlatform.instance.arrayUnion([123])); _checkEncodeDecode( - codec, FieldValueFactory.instance.arrayRemove([123])); - _checkEncodeDecode(codec, FieldValueFactory.instance.delete()); + codec, FieldValueFactoryPlatform.instance.arrayRemove([123])); + _checkEncodeDecode(codec, FieldValueFactoryPlatform.instance.delete()); _checkEncodeDecode( - codec, FieldValueFactory.instance.serverTimestamp()); + codec, FieldValueFactoryPlatform.instance.serverTimestamp()); _checkEncodeDecode( - codec, FieldValueFactory.instance.increment(1.0)); + codec, FieldValueFactoryPlatform.instance.increment(1.0)); _checkEncodeDecode( - codec, FieldValueFactory.instance.increment(1)); + codec, FieldValueFactoryPlatform.instance.increment(1)); }); test('encode and decode FieldPath', () { @@ -1395,8 +1395,8 @@ bool _deepEquals(dynamic valueA, dynamic valueB) { if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; - if (valueA is FieldValue) { - return valueB is FieldValue && _deepEqualsFieldValue(valueA, valueB); + if (valueA is FieldValuePlatform) { + return valueB is FieldValuePlatform && _deepEqualsFieldValue(valueA, valueB); } if (valueA is FieldPath) { return valueB is FieldPath && valueA.type == valueB.type; @@ -1444,7 +1444,7 @@ bool _deepEqualsMap( return true; } -bool _deepEqualsFieldValue(FieldValue valueA, FieldValue valueB) { +bool _deepEqualsFieldValue(FieldValuePlatform valueA, FieldValuePlatform valueB) { if (valueA.type != valueB.type) return false; if (valueA.value == null) return valueB.value == null; if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index f57890d85b28..dab2f1e596a9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -81,7 +81,7 @@ void main() { }); } -void _assertGetMethodCalled(DocumentReference documentReference, Source source, +void _assertGetMethodCalled(DocumentReferencePlatform documentReference, Source source, String expectedSourceString) async { bool isMethodCalled = false; handleMethodCall((call) { @@ -104,7 +104,7 @@ void _assertGetMethodCalled(DocumentReference documentReference, Source source, reason: "DocumentReference.get was not called"); } -void _assertSetDataMethodCalled(DocumentReference documentReference, +void _assertSetDataMethodCalled(DocumentReferencePlatform documentReference, bool expectedMergeValue, FieldValueInterface fieldValue) async { bool isMethodCalled = false; final Map data = {"test": "test"}; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart index 798a1dfd00d0..7bf80c06b11f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart @@ -12,7 +12,7 @@ class TestQuery extends MethodChannelQuery { void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$Query()", () { + group("$QueryPlatform()", () { test("parameters", () { _hasDefaultParameters(TestQuery._().parameters); }); @@ -20,7 +20,7 @@ void main() { test("reference", () { final testQuery = TestQuery._(); final actualCollection = testQuery.reference(); - expect(actualCollection, isInstanceOf()); + expect(actualCollection, isInstanceOf()); expect(actualCollection.path, equals(_kQueryPath)); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 8b24bd0fd455..da8ab568a53e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -4,7 +4,7 @@ import 'package:mockito/mockito.dart'; import 'test_common.dart'; -class MockDocumentReference extends Mock implements DocumentReference {} +class MockDocumentReference extends Mock implements DocumentReferencePlatform {} class MockFiledValue extends Mock implements FieldValueInterface {} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 19560e77373d..4809aedf9008 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; -/// Web implementation for Firestore [CollectionReference] -class CollectionReferenceWeb implements CollectionReference { +/// Web implementation for Firestore [CollectionReferencePlatform] +class CollectionReferenceWeb implements CollectionReferencePlatform { /// instance of Firestore from the web plugin final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; @@ -18,7 +18,7 @@ class CollectionReferenceWeb implements CollectionReference { webFirestore.collection(pathComponents.join("/"))); @override - DocumentReference parent() { + DocumentReferencePlatform parent() { if (pathComponents.length < 2) { return null; } @@ -30,7 +30,7 @@ class CollectionReferenceWeb implements CollectionReference { } @override - DocumentReference document([String path]) { + DocumentReferencePlatform document([String path]) { List childPath; if (path == null) { final String key = AutoIdGenerator.autoId(); @@ -46,8 +46,8 @@ class CollectionReferenceWeb implements CollectionReference { } @override - Future add(Map data) async { - final DocumentReference newDocument = document(); + Future add(Map data) async { + final DocumentReferencePlatform newDocument = document(); await newDocument.setData(data); return newDocument; } @@ -56,25 +56,25 @@ class CollectionReferenceWeb implements CollectionReference { Map buildArguments() => queryDelegate.buildArguments(); @override - Query endAt(List values) { + QueryPlatform endAt(List values) { _resetQueryDelegate(); return queryDelegate.endAt(values); } @override - Query endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); return queryDelegate.endAtDocument(documentSnapshot); } @override - Query endBefore(List values) { + QueryPlatform endBefore(List values) { _resetQueryDelegate(); return queryDelegate.endBefore(values); } @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); return queryDelegate.endBeforeDocument(documentSnapshot); } @@ -83,7 +83,7 @@ class CollectionReferenceWeb implements CollectionReference { FirestorePlatform get firestore => _firestorePlatform; @override - Future getDocuments({Source source = Source.serverAndCache}) => + Future getDocuments({Source source = Source.serverAndCache}) => queryDelegate.getDocuments(source: source); @override @@ -93,13 +93,13 @@ class CollectionReferenceWeb implements CollectionReference { bool get isCollectionGroup => false; @override - Query limit(int length) { + QueryPlatform limit(int length) { _resetQueryDelegate(); return queryDelegate.limit(length); } @override - Query orderBy(field, {bool descending = false}) { + QueryPlatform orderBy(field, {bool descending = false}) { _resetQueryDelegate(); return queryDelegate.orderBy(field, descending: descending); } @@ -111,38 +111,38 @@ class CollectionReferenceWeb implements CollectionReference { String get path => pathComponents.join("/"); @override - CollectionReference reference() => queryDelegate.reference(); + CollectionReferencePlatform reference() => queryDelegate.reference(); @override - Stream snapshots({bool includeMetadataChanges = false}) => + Stream snapshots({bool includeMetadataChanges = false}) => queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); @override - Query startAfter(List values) { + QueryPlatform startAfter(List values) { _resetQueryDelegate(); return queryDelegate.startAfter(values); } @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); return queryDelegate.startAfterDocument(documentSnapshot); } @override - Query startAt(List values) { + QueryPlatform startAt(List values) { _resetQueryDelegate(); return queryDelegate.startAt(values); } @override - Query startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { _resetQueryDelegate(); return queryDelegate.startAtDocument(documentSnapshot); } @override - Query where(field, + QueryPlatform where(field, {isEqualTo, isLessThan, isLessThanOrEqualTo, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart index 5d2a1ac40172..72e640b18a66 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; -/// Web implementation for firestore [DocumentReference] -class DocumentReferenceWeb extends DocumentReference { +/// Web implementation for firestore [DocumentReferencePlatform] +class DocumentReferenceWeb extends DocumentReferencePlatform { /// instance of Firestore from the web plugin final web.Firestore firestoreWeb; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 87a0b6c57302..d2ff554d76e2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -1,8 +1,8 @@ part of cloud_firestore_web; -/// An implementation of [FieldValueFactory] which builds [FieldValue] +/// An implementation of [FieldValueFactoryPlatform] which builds [FieldValuePlatform] /// instance that is [jsify] friendly -class FieldValueFactoryWeb implements FieldValueFactory { +class FieldValueFactoryWeb implements FieldValueFactoryPlatform { @override FieldValueInterface arrayRemove(List elements) { final delegate = web.FieldValue.arrayRemove(elements); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index c255d0dad17d..1f627f2396b2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -1,6 +1,6 @@ part of cloud_firestore_web; -/// Implementation of [FieldValue] that is compatible with +/// Implementation of [FieldValuePlatform] that is compatible with /// firestore web plugin class FieldValueWeb implements FieldValueInterface, web.FieldValue { web.FieldValue _delegate; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 552790ce03f2..0ed957335eaa 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -10,21 +10,13 @@ import 'package:js/js_util.dart'; import 'package:meta/meta.dart'; part 'collection_reference_web.dart'; - part 'utils/codec_utility.dart'; - part 'utils/document_reference_utils.dart'; - part 'field_value_factory_web.dart'; - part 'document_reference_web.dart'; - part 'query_web.dart'; - part 'transaction_web.dart'; - part 'field_value_web.dart'; - part 'write_batch_web.dart'; /// Web implementation for [FirestorePlatform] @@ -44,25 +36,25 @@ class FirestoreWeb extends FirestorePlatform { : webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), super(app: app ?? FirebaseApp.instance) { - FieldValueFactory.instance = FieldValueFactoryWeb(); + FieldValueFactoryPlatform.instance = FieldValueFactoryWeb(); } @override FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); @override - CollectionReference collection(String path) { + CollectionReferencePlatform collection(String path) { return CollectionReferenceWeb(this, webFirestore, path.split('/')); } @override - Query collectionGroup(String path) { + QueryPlatform collectionGroup(String path) { return QueryWeb(this, path, webFirestore.collectionGroup(path), isCollectionGroup: true); } @override - DocumentReference document(String path) => + DocumentReferencePlatform document(String path) => DocumentReferenceWeb(webFirestore, this, path.split('/')); @override diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index dfac4340ac4b..e7f84ea6fcbb 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; -/// Web implementation for firestore [Query] -class QueryWeb implements Query { +/// Web implementation for firestore [QueryPlatform] +class QueryWeb implements QueryPlatform { final web.Query _webQuery; final FirestorePlatform _firestore; final bool _isCollectionGroup; @@ -19,7 +19,7 @@ class QueryWeb implements Query { this._orderByKeys = orderByKeys ?? []; @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({bool includeMetadataChanges = false}) { assert(_webQuery != null); Stream querySnapshots = _webQuery.onSnapshot; if (includeMetadataChanges) { @@ -29,7 +29,7 @@ class QueryWeb implements Query { } @override - Future getDocuments( + Future getDocuments( {Source source = Source.serverAndCache}) async { assert(_webQuery != null); return _webQuerySnapshotToQuerySnapshot(await _webQuery.get()); @@ -39,12 +39,12 @@ class QueryWeb implements Query { Map buildArguments() => Map(); @override - Query endAt(List values) => QueryWeb(this._firestore, this._path, + QueryPlatform endAt(List values) => QueryWeb(this._firestore, this._path, _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); @override - Query endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -56,12 +56,12 @@ class QueryWeb implements Query { } @override - Query endBefore(List values) => QueryWeb(this._firestore, this._path, + QueryPlatform endBefore(List values) => QueryWeb(this._firestore, this._path, _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, isCollectionGroup: _isCollectionGroup); @override - Query endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -79,7 +79,7 @@ class QueryWeb implements Query { bool get isCollectionGroup => _isCollectionGroup; @override - Query limit(int length) => QueryWeb( + QueryPlatform limit(int length) => QueryWeb( this._firestore, this._path, _webQuery != null ? _webQuery.limit(length) : null, @@ -88,7 +88,7 @@ class QueryWeb implements Query { ); @override - Query orderBy(field, {bool descending = false}) { + QueryPlatform orderBy(field, {bool descending = false}) { dynamic usableField = field; if (field == FieldPath.documentId) { usableField = web.FieldPath.documentId(); @@ -109,15 +109,15 @@ class QueryWeb implements Query { List get pathComponents => this._path.split("/"); @override - CollectionReference reference() => firestore.collection(_path); + CollectionReferencePlatform reference() => firestore.collection(_path); @override - Query startAfter(List values) => QueryWeb( + QueryPlatform startAfter(List values) => QueryWeb( this._firestore, this._path, _webQuery.startAfter(fieldValues: values), orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); @override - Query startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -130,7 +130,7 @@ class QueryWeb implements Query { } @override - Query startAt(List values) => QueryWeb( + QueryPlatform startAt(List values) => QueryWeb( this._firestore, this._path, _webQuery.startAt(fieldValues: values), @@ -139,7 +139,7 @@ class QueryWeb implements Query { ); @override - Query startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -152,7 +152,7 @@ class QueryWeb implements Query { } @override - Query where(field, + QueryPlatform where(field, {isEqualTo, isLessThan, isLessThanOrEqualTo, @@ -210,9 +210,9 @@ class QueryWeb implements Query { orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); } - QuerySnapshot _webQuerySnapshotToQuerySnapshot( + QuerySnapshotPlatform _webQuerySnapshotToQuerySnapshot( web.QuerySnapshot webSnapshot) { - return QuerySnapshot( + return QuerySnapshotPlatform( webSnapshot.docs .map((webSnapshot) => _fromWebDocumentSnapshotToPlatformDocumentSnapshot( @@ -222,8 +222,8 @@ class QueryWeb implements Query { _webMetadataToMetada(webSnapshot.metadata)); } - DocumentChange _webChangeToChange(web.DocumentChange webChange) { - return DocumentChange( + DocumentChangePlatform _webChangeToChange(web.DocumentChange webChange) { + return DocumentChangePlatform( _fromString(webChange.type), webChange.oldIndex, webChange.newIndex, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index 7cb905cbaf33..dc43b72625b4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -11,14 +11,14 @@ class TransactionWeb implements TransactionPlatform { TransactionWeb(this._webTransaction, this.firestore); @override - Future delete(DocumentReference documentReference) async { + Future delete(DocumentReferencePlatform documentReference) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction .delete((documentReference as DocumentReferenceWeb).delegate); } @override - Future get(DocumentReference documentReference) async { + Future get(DocumentReferencePlatform documentReference) async { assert(documentReference is DocumentReferenceWeb); final webSnapshot = await _webTransaction .get((documentReference as DocumentReferenceWeb).delegate); @@ -28,7 +28,7 @@ class TransactionWeb implements TransactionPlatform { @override Future set( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, @@ -37,7 +37,7 @@ class TransactionWeb implements TransactionPlatform { @override Future update( - DocumentReference documentReference, Map data) async { + DocumentReferencePlatform documentReference, Map data) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 8b022770921d..6cbcdfcc6f27 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -14,13 +14,13 @@ class WriteBatchWeb implements WriteBatchPlatform { } @override - void delete(DocumentReference document) { + void delete(DocumentReferencePlatform document) { assert(document is DocumentReferenceWeb); _delegate.delete((document as DocumentReferenceWeb).delegate); } @override - void setData(DocumentReference document, Map data, + void setData(DocumentReferencePlatform document, Map data, {bool merge = false}) { assert(document is DocumentReferenceWeb); _delegate.set( @@ -30,7 +30,7 @@ class WriteBatchWeb implements WriteBatchPlatform { } @override - void updateData(DocumentReference document, Map data) { + void updateData(DocumentReferencePlatform document, Map data) { assert(document is DocumentReferenceWeb); _delegate.update((document as DocumentReferenceWeb).delegate, data: CodecUtility.encodeMapData(data)); From 182d2ae477bf172640c538a28f41a2c1e245674e Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Wed, 29 Jan 2020 13:40:20 -0800 Subject: [PATCH 109/144] Ensure platform interfaces can only be extended, not implemented. As expected, this breaks Web, for now: ``` 00:07 +19 -23: /usr/local/google/home/dit/github/flutterfire/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart: DocumentReferenceWeb() snapshots [E] NoSuchMethodError: '_instanceToken' method not found Receiver: Instance of 'FieldValueFactoryWeb' Arguments: [] package:dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 196:49 throw_ package:dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 667:3 defaultNoSuchMethod package:dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 63:12 noSuchMethod package:cloud_firestore_web/field_value_factory_web.dart 40:3 get [_instanceToken] package:plugin_platform_interface/plugin_platform_interface.dart 72:35 verifyToken package:cloud_firestore_platform_interface/src/platform_interface/field_value_factory.dart 36:23 set instance package:cloud_firestore_web/firestore_web.dart 39:31 new ``` --- .../collection_reference.dart | 1 + .../platform_interface/document_change.dart | 6 +++-- .../document_reference.dart | 6 +++-- .../src/platform_interface/field_value.dart | 6 +++-- .../field_value_factory.dart | 25 ++++++++++++++----- .../lib/src/platform_interface/query.dart | 7 ++++-- .../platform_interface/query_snapshot.dart | 6 +++-- .../src/platform_interface/transaction.dart | 6 +++-- .../src/platform_interface/write_batch.dart | 6 +++-- 9 files changed, 49 insertions(+), 20 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index e8479d2e7e95..179dbedc90f2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -7,6 +7,7 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [QueryPlatform]). +/// Note: QueryPlatform extends PlatformInterface already. abstract class CollectionReferencePlatform extends QueryPlatform { /// Create a [CollectionReferencePlatform] using [pathComponents] CollectionReferencePlatform(FirestorePlatform firestore, List pathComponents) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index cc08d7d63ccb..4b4183aec5f4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -22,9 +22,11 @@ enum DocumentChangeType { /// /// It contains the document affected and the type of change that occurred /// (added, modified, or removed). -class DocumentChangePlatform { +class DocumentChangePlatform extends PlatformInterface { /// Create a [DocumentChangePlatform] - DocumentChangePlatform(this.type, this.oldIndex, this.newIndex, this.document); + DocumentChangePlatform(this.type, this.oldIndex, this.newIndex, this.document) : super(token: _token); + + static final Object _token = Object(); /// The type of change that occurred (added, modified, or removed). final DocumentChangeType type; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index da067a6c6c34..063b844a043c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -6,9 +6,11 @@ part of cloud_firestore_platform_interface; /// The document at the referenced location may or may not exist. /// A [DocumentReferencePlatform] can also be used to create a [CollectionReferencePlatform] /// to a subcollection. -abstract class DocumentReferencePlatform { +abstract class DocumentReferencePlatform extends PlatformInterface { /// Create instance of [DocumentReferencePlatform] - DocumentReferencePlatform(this.firestore, this._pathComponents); + DocumentReferencePlatform(this.firestore, this._pathComponents) : super(token: _token); + + static final Object _token = Object(); /// The Firestore instance associated with this document reference final FirestorePlatform firestore; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index e07115d87a5e..d7e16cef7d02 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -18,7 +18,7 @@ abstract class FieldValueInterface { } /// Platform Interface of a FieldValue; implementation for [FieldValueInterface] -class FieldValuePlatform implements FieldValueInterface { +class FieldValuePlatform extends PlatformInterface implements FieldValueInterface { /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValuePlatform] static Map serverDelegates(Map data) { @@ -36,7 +36,9 @@ class FieldValuePlatform implements FieldValueInterface { return output; } - FieldValuePlatform._(this.type, this.value); + static final Object _token = Object(); + + FieldValuePlatform._(this.type, this.value) : super(token: _token); @override FieldValueInterface get instance => this; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 819a13850df6..3f5fef0f6ece 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -24,7 +24,7 @@ enum FieldValueType { /// An interface for a factory that is used to build [FieldValuePlatform] according to /// Platform (web or mobile) -abstract class FieldValueFactoryPlatform { +abstract class FieldValueFactoryPlatform extends PlatformInterface { /// Current instance of [FieldValueFactoryPlatform] static FieldValueFactoryPlatform get instance => _instance; @@ -33,9 +33,12 @@ abstract class FieldValueFactoryPlatform { /// Sets the default instance of [FieldValueFactoryPlatform] which is used to build /// [FieldValuePlatform] items static set instance(FieldValueFactoryPlatform instance) { + PlatformInterface.verifyToken(instance, _token); _instance = instance; } + static final Object _token = Object(); + /// Returns a special value that tells the server to union the given elements /// with any array value that already exists on the server. /// @@ -43,7 +46,9 @@ abstract class FieldValueFactoryPlatform { /// added to the end. If the field being modified is not already an array it /// will be overwritten with an array containing exactly the specified /// elements. - FieldValueInterface arrayUnion(List elements); + FieldValueInterface arrayUnion(List elements) { + throw UnimplementedError("arrayUnion() is not implemented"); + } /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -51,16 +56,24 @@ abstract class FieldValueFactoryPlatform { /// All instances of each element specified will be removed from the array. /// If the field being modified is not already an array it will be overwritten /// with an empty array. - FieldValueInterface arrayRemove(List elements); + FieldValueInterface arrayRemove(List elements) { + throw UnimplementedError("arrayRemove() is not implemented"); + } /// Returns a sentinel for use with update() to mark a field for deletion. - FieldValueInterface delete(); + FieldValueInterface delete() { + throw UnimplementedError("delete() is not implemented"); + } /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. - FieldValueInterface serverTimestamp(); + FieldValueInterface serverTimestamp() { + throw UnimplementedError("serverTimestamp() is not implemented"); + } /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - FieldValueInterface increment(num value); + FieldValueInterface increment(num value) { + throw UnimplementedError("increment() is not implemented"); + } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index be8a7f06ee05..b757dd296b66 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -5,7 +5,7 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. -abstract class QueryPlatform { +abstract class QueryPlatform extends PlatformInterface { /// Create a [QueryPlatform] instance QueryPlatform( {@required this.firestore, @@ -20,7 +20,10 @@ abstract class QueryPlatform { 'orderBy': List>.unmodifiable(>[]), }), assert(firestore != null), - assert(pathComponents != null); + assert(pathComponents != null), + super(token: _token); + + static final Object _token = Object(); /// The Firestore instance associated with this query final FirestorePlatform firestore; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 02c42343fe3c..98ff8fc4ccfc 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -5,9 +5,11 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. -class QuerySnapshotPlatform { +class QuerySnapshotPlatform extends PlatformInterface { /// Create a [QuerySnapshotPlatform] - QuerySnapshotPlatform(this.documents, this.documentChanges, this.metadata); + QuerySnapshotPlatform(this.documents, this.documentChanges, this.metadata) : super(token: _token); + + static final Object _token = Object(); /// Gets a list of all the documents included in this snapshot final List documents; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 1be366150351..bb1daec2125d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -9,11 +9,13 @@ part of cloud_firestore_platform_interface; typedef Future TransactionHandler(TransactionPlatform transaction); /// a [TransactionPlatform] is a set of read and write operations on one or more documents. -abstract class TransactionPlatform { +abstract class TransactionPlatform extends PlatformInterface { // disabling lint as it's only visible for testing // ignore: public_member_api_docs @visibleForTesting - TransactionPlatform(this._transactionId, this.firestore); + TransactionPlatform(this._transactionId, this.firestore) : super(token: _token); + + static final Object _token = Object(); int _transactionId; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index f6e565bc9b53..2680309b094f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -10,8 +10,10 @@ part of cloud_firestore_platform_interface; /// /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. -abstract class WriteBatchPlatform { - WriteBatchPlatform._(); +abstract class WriteBatchPlatform extends PlatformInterface { + WriteBatchPlatform._() : super(token: _token); + + static final Object _token = Object(); /// Indicator to whether or not this [WriteBatch] has been committed. bool _committed = false; From 082ae1daf2f1d84174327ea68108f295fae34747 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 29 Jan 2020 13:43:18 -0800 Subject: [PATCH 110/144] MethodChannelFieldValueFactory now extends FieldValueFactoryPlatform --- .../src/method_channel/method_channel_field_value_factory.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 792479e61e9a..3568ded1fd0d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -2,7 +2,7 @@ part of cloud_firestore_platform_interface; /// An implementation of [FieldValueFactoryPlatform] that is suitable to be used /// on mobile where communication relies on [MethodChannel] -class MethodChannelFieldValueFactory implements FieldValueFactoryPlatform { +class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { @override FieldValuePlatform arrayRemove(List elements) => FieldValuePlatform._(FieldValueType.arrayRemove, elements); From e7be32a0db431870a968142e03471339dd2c4401 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Wed, 29 Jan 2020 14:52:14 -0800 Subject: [PATCH 111/144] .appName() -> .app.name --- .../cloud_firestore/lib/src/firestore.dart | 2 -- .../method_channel_document_reference.dart | 10 +++++----- .../lib/src/method_channel/method_channel_query.dart | 4 ++-- .../src/method_channel/method_channel_transaction.dart | 8 ++++---- .../src/method_channel/method_channel_write_batch.dart | 8 ++++---- .../lib/src/method_channel_firestore.dart | 3 --- .../lib/src/utils/firestore_message_codec.dart | 2 +- .../test/method_channel_cloud_firestore_test.dart | 2 +- .../test/test_common.dart | 2 +- .../test/transaction_test.dart | 2 +- .../cloud_firestore_web/lib/firestore_web.dart | 3 --- .../cloud_firestore_web/test/transaction_web_test.dart | 2 +- .../cloud_firestore_web/test/write_batch_web_test.dart | 2 +- 13 files changed, 21 insertions(+), 29 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index 1e7b0f0052e3..cf9bd3d64c13 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -36,8 +36,6 @@ class Firestore { /// If null, the default [FirebaseApp] is used. FirebaseApp get app => _delegate.app; - String appName() => _delegate.appName(); - /// Creates a write batch, used for performing multiple writes as a single /// atomic operation. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index e80f8b75022d..316fe50f6f6b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -18,7 +18,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { return MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#setData', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'data': FieldValuePlatform.serverDelegates(data), 'options': {'merge': merge}, @@ -31,7 +31,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { return MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#updateData', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'data': FieldValuePlatform.serverDelegates(data), }, @@ -44,7 +44,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { await MethodChannelFirestore.channel.invokeMapMethod( 'DocumentReference#get', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'source': _getSourceString(source), }, @@ -62,7 +62,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { Future delete() { return MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#delete', - {'app': firestore.appName(), 'path': path}, + {'app': firestore.app.name, 'path': path}, ); } @@ -79,7 +79,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { _handle = MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#addSnapshotListener', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'includeMetadataChanges': includeMetadataChanges, }, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index dbb992d5b1fa..89f6f82f9aff 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -43,7 +43,7 @@ class MethodChannelQuery extends QueryPlatform { _handle = MethodChannelFirestore.channel.invokeMethod( 'Query#addSnapshotListener', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'isCollectionGroup': isCollectionGroup, 'parameters': parameters, @@ -75,7 +75,7 @@ class MethodChannelQuery extends QueryPlatform { await MethodChannelFirestore.channel.invokeMapMethod( 'Query#getDocuments', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'path': path, 'isCollectionGroup': isCollectionGroup, 'parameters': parameters, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index b9db5efa338d..8067f623c56f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -25,7 +25,7 @@ class Transaction extends TransactionPlatform { Future _get(DocumentReferencePlatform documentReference) async { final Map result = await MethodChannelFirestore.channel .invokeMapMethod('Transaction#get', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, }); @@ -45,7 +45,7 @@ class Transaction extends TransactionPlatform { Future _delete(DocumentReferencePlatform documentReference) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#delete', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, }); @@ -56,7 +56,7 @@ class Transaction extends TransactionPlatform { DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#update', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, 'data': FieldValuePlatform.serverDelegates(data), @@ -68,7 +68,7 @@ class Transaction extends TransactionPlatform { DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#set', { - 'app': firestore.appName(), + 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, 'data': FieldValuePlatform.serverDelegates(data), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index ca205b5a91bd..112d3b04d0c2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -15,7 +15,7 @@ class WriteBatch extends WriteBatchPlatform { WriteBatch(this._firestore) : _handle = MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#create', - {'app': _firestore.appName()}), + {'app': _firestore.app.name}), super._(); final FirestorePlatform _firestore; @@ -41,7 +41,7 @@ class WriteBatch extends WriteBatchPlatform { MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#delete', { - 'app': _firestore.appName(), + 'app': _firestore.app.name, 'handle': handle, 'path': document.path, }, @@ -60,7 +60,7 @@ class WriteBatch extends WriteBatchPlatform { MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#setData', { - 'app': _firestore.appName(), + 'app': _firestore.app.name, 'handle': handle, 'path': document.path, 'data': FieldValuePlatform.serverDelegates(data), @@ -80,7 +80,7 @@ class WriteBatch extends WriteBatchPlatform { MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#updateData', { - 'app': _firestore.appName(), + 'app': _firestore.app.name, 'handle': handle, 'path': document.path, 'data': FieldValuePlatform.serverDelegates(data) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart index 58d7ca09d886..d0c493a6e05a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart @@ -133,7 +133,4 @@ class MethodChannelFirestore extends FirestorePlatform { 'cacheSizeBytes': cacheSizeBytes, }); } - - @override - String appName() => app.name; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart index 7f7add8b5af8..747673040944 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart @@ -56,7 +56,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putFloat64(value.longitude); } else if (value is DocumentReferencePlatform) { buffer.putUint8(_kDocumentReference); - final List appName = utf8.encoder.convert(value.firestore.appName()); + final List appName = utf8.encoder.convert(value.firestore.app.name); writeSize(buffer, appName.length); buffer.putUint8List(appName); final List bytes = utf8.encoder.convert(value.path); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index ab4653ab6481..86eaa727c0fa 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -47,7 +47,7 @@ void main() { firestore = MethodChannelFirestore(app: app); collectionReference = firestore.collection('foo'); collectionGroupQuery = firestore.collectionGroup('bar'); - transaction = Transaction(0, firestore.appName()); + transaction = Transaction(0, firestore.app.name); MethodChannelFirestore.channel .setMockMethodCallHandler((MethodCall methodCall) async { log.add(methodCall); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index 307c9b89f31d..2fa304987917 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -10,7 +10,7 @@ const kDocumentId = "document"; void handleMethodCall(MethodCallCallback methodCallCallback) => MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { expect( - call.arguments["app"], equals(FirestorePlatform.instance.appName())); + call.arguments["app"], equals(FirestorePlatform.instance.app.name)); expect(call.arguments["path"], equals("$kCollectionId/$kDocumentId")); return await methodCallCallback(call); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index da8ab568a53e..6ea6ad5f3fd8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -20,7 +20,7 @@ void main() { when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); setUp(() { transaction = - Transaction(_kTransactionId, FirestorePlatform.instance.appName()); + Transaction(_kTransactionId, FirestorePlatform.instance.app.name); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index 0ed957335eaa..b45a468d20f5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -97,7 +97,4 @@ class FirestoreWeb extends FirestorePlatform { }).timeout(timeout); return result is Map ? result : {}; } - - @override - String appName() => app.name; } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index c45efc65fb8c..1c6b350d051f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -13,7 +13,7 @@ void main() { final transaction = TransactionWeb(mockWebTransaction, mockFirestore); setUp(() { - when(mockFirestore.appName()).thenReturn("test"); + when(mockFirestore.app.name).thenReturn("test"); when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart index b96c1f8ed0d5..bed4078bc5ca 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -14,7 +14,7 @@ void main() { final transaction = WriteBatchWeb(mockWebTransaction); setUp(() { - when(mockFirestore.appName()).thenReturn("test"); + when(mockFirestore.app.name).thenReturn("test"); when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); }); From b036a96de40a7b6646aae43c491df237d5596e92 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Wed, 29 Jan 2020 15:50:24 -0800 Subject: [PATCH 112/144] Ensure PlatformInterface _delegate classes extend the Platform class, and not implement it. Add static verifyExtends method to Platform classes. --- .../cloud_firestore/lib/src/document_change.dart | 4 +++- .../cloud_firestore/lib/src/document_reference.dart | 4 +++- .../cloud_firestore/lib/src/field_value.dart | 6 ++++-- .../cloud_firestore/cloud_firestore/lib/src/query.dart | 4 +++- .../cloud_firestore/lib/src/query_snapshot.dart | 4 +++- .../cloud_firestore/lib/src/transaction.dart | 4 +++- .../cloud_firestore/lib/src/write_batch.dart | 4 +++- .../lib/src/platform_interface/document_change.dart | 9 +++++++++ .../lib/src/platform_interface/document_reference.dart | 9 +++++++++ .../lib/src/platform_interface/field_value.dart | 9 +++++++++ .../lib/src/platform_interface/field_value_factory.dart | 9 +++++++++ .../lib/src/platform_interface/query.dart | 9 +++++++++ .../lib/src/platform_interface/query_snapshot.dart | 9 +++++++++ .../lib/src/platform_interface/transaction.dart | 9 +++++++++ .../lib/src/platform_interface/write_batch.dart | 9 +++++++++ 15 files changed, 94 insertions(+), 8 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index f3e9422e7891..d26018145684 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -26,7 +26,9 @@ class DocumentChange { final platform.DocumentChangePlatform _delegate; final Firestore _firestore; - DocumentChange._(this._delegate, this._firestore); + DocumentChange._(this._delegate, this._firestore) { + platform.DocumentChangePlatform.verifyExtends(_delegate); + } /// The type of change that occurred (added, modified, or removed). DocumentChangeType get type => _PlatformUtils.fromPlatform(_delegate.type); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index 5c2bfe547cbe..f803ff36c0b8 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -16,7 +16,9 @@ class DocumentReference { /// The Firestore instance associated with this document reference final Firestore firestore; - DocumentReference._(this._delegate, this.firestore); + DocumentReference._(this._delegate, this.firestore) { + platform.DocumentReferencePlatform.verifyExtends(_delegate); + } @override bool operator ==(dynamic o) => diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 1a522e51ec59..0b7486037909 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -7,9 +7,11 @@ part of cloud_firestore; /// Sentinel values that can be used when writing document fields with set() or /// update(). class FieldValue implements platform.FieldValueInterface { - platform.FieldValueInterface _delegate; + platform.FieldValuePlatform _delegate; - FieldValue._(this._delegate); + FieldValue._(this._delegate) { + platform.FieldValuePlatform.verifyExtends(_delegate); + } @override platform.FieldValueInterface get instance => _delegate; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 8a38eb1aa5de..9ad2a24fe6fd 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -11,7 +11,9 @@ class Query { /// The Firestore instance associated with this query final Firestore firestore; - Query._(this._delegate, this.firestore); + Query._(this._delegate, this.firestore) { + platform.QueryPlatform.verifyExtends(_delegate); + } List get _pathComponents => _delegate.pathComponents; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart index 2a5100c0575a..51bde9c9cc6d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query_snapshot.dart @@ -9,7 +9,9 @@ class QuerySnapshot { final platform.QuerySnapshotPlatform _delegate; final Firestore _firestore; - QuerySnapshot._(this._delegate, this._firestore); + QuerySnapshot._(this._delegate, this._firestore) { + platform.QuerySnapshotPlatform.verifyExtends(_delegate); + } /// Gets a list of all the documents included in this snapshot List get documents => _delegate.documents diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart index ca5a906a8067..60a7cf8a939d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/transaction.dart @@ -11,7 +11,9 @@ typedef Future TransactionHandler(Transaction transaction); class Transaction { final Firestore _firestore; - Transaction._(this._delegate, this._firestore); + Transaction._(this._delegate, this._firestore) { + platform.TransactionPlatform.verifyExtends(_delegate); + } platform.TransactionPlatform _delegate; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart index fa42f63080a0..92c6eb147864 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/write_batch.dart @@ -14,7 +14,9 @@ part of cloud_firestore; class WriteBatch { final platform.WriteBatchPlatform _delegate; - WriteBatch._(this._delegate); + WriteBatch._(this._delegate) { + platform.WriteBatchPlatform.verifyExtends(_delegate); + } Future commit() => _delegate.commit(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 4b4183aec5f4..b083f7529eed 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -28,6 +28,15 @@ class DocumentChangePlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [DocumentChangePlatform]. + /// This is used by the app-facing [DocumentChange] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(DocumentChangePlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// The type of change that occurred (added, modified, or removed). final DocumentChangeType type; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 063b844a043c..81694c57c5ba 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -12,6 +12,15 @@ abstract class DocumentReferencePlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [DocumentReferencePlatform]. + /// This is used by the app-facing [DocumentReference] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(DocumentReferencePlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// The Firestore instance associated with this document reference final FirestorePlatform firestore; final List _pathComponents; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index d7e16cef7d02..a94896f3c236 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -38,6 +38,15 @@ class FieldValuePlatform extends PlatformInterface implements FieldValueInterfac static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [FieldValuePlatform]. + /// This is used by the app-facing [FieldValue] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(FieldValuePlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + FieldValuePlatform._(this.type, this.value) : super(token: _token); @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 3f5fef0f6ece..cf216930a85d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -39,6 +39,15 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [FieldValueFactoryPlatform]. + /// This is used by the app-facing [FieldValueFactory] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(FieldValueFactoryPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// Returns a special value that tells the server to union the given elements /// with any array value that already exists on the server. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index b757dd296b66..3a06672b7536 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -25,6 +25,15 @@ abstract class QueryPlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [QueryPlatform]. + /// This is used by the app-facing [Query] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(QueryPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// The Firestore instance associated with this query final FirestorePlatform firestore; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 98ff8fc4ccfc..5fec024d6bdf 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -11,6 +11,15 @@ class QuerySnapshotPlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [QuerySnapshotPlatform]. + /// This is used by the app-facing [QuerySnapshot] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(QuerySnapshotPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// Gets a list of all the documents included in this snapshot final List documents; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index bb1daec2125d..a2a61f240fc6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -17,6 +17,15 @@ abstract class TransactionPlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [TransactionPlatform]. + /// This is used by the app-facing [Transaction] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(TransactionPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + int _transactionId; /// [FirestorePlatform] instance used for this [TransactionPlatform] diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index 2680309b094f..823afae8c560 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -15,6 +15,15 @@ abstract class WriteBatchPlatform extends PlatformInterface { static final Object _token = Object(); + /// Throws an [AssertionError] if [instance] does not extend + /// [WriteBatchPlatform]. + /// This is used by the app-facing [WriteBatch] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(WriteBatchPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + /// Indicator to whether or not this [WriteBatch] has been committed. bool _committed = false; From c2c75d079bf5731716f5ef37e2f1fe64a65648bb Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 29 Jan 2020 18:21:14 -0800 Subject: [PATCH 113/144] Get web going again... --- .../method_channel_collection_reference.dart | 7 +++++++ .../method_channel_field_value_factory.dart | 12 ++++++------ .../method_channel/method_channel_write_batch.dart | 2 +- .../lib/src/platform_interface/field_value.dart | 2 +- .../src/platform_interface/field_value_factory.dart | 2 +- .../lib/src/platform_interface/query.dart | 4 +++- .../lib/src/platform_interface/write_batch.dart | 3 ++- .../lib/collection_reference_web.dart | 5 +++-- .../lib/field_value_factory_web.dart | 2 +- .../cloud_firestore_web/lib/field_value_web.dart | 4 ++-- .../cloud_firestore_web/lib/query_web.dart | 5 +++-- .../cloud_firestore_web/lib/transaction_web.dart | 6 ++++-- .../cloud_firestore_web/lib/write_batch_web.dart | 2 +- 13 files changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index c72cedffc5c5..d7d1276f21dd 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -7,6 +7,13 @@ part of cloud_firestore_platform_interface; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods /// inherited from [QueryPlatform]). +/// +/// Note that this class *should* extend CollectionReferencePlatform, but +/// it doesn't because of the extensive changes required to MethodChannelQuery +/// (which *does* extend its Platform class). +/// +/// If you changed CollectionReferencePlatform and this class started throwing +/// compilation errors, now you know why it is. class MethodChannelCollectionReference extends MethodChannelQuery implements CollectionReferencePlatform { /// Create a [MethodChannelCollectionReference] from [pathComponents] diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 3568ded1fd0d..0c0052fe0237 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -5,14 +5,14 @@ part of cloud_firestore_platform_interface; class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { @override FieldValuePlatform arrayRemove(List elements) => - FieldValuePlatform._(FieldValueType.arrayRemove, elements); + FieldValuePlatform(FieldValueType.arrayRemove, elements); @override FieldValuePlatform arrayUnion(List elements) => - FieldValuePlatform._(FieldValueType.arrayUnion, elements); + FieldValuePlatform(FieldValueType.arrayUnion, elements); @override - FieldValuePlatform delete() => FieldValuePlatform._(FieldValueType.delete, null); + FieldValuePlatform delete() => FieldValuePlatform(FieldValueType.delete, null); @override FieldValuePlatform increment(num value) { @@ -20,14 +20,14 @@ class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { // attempt to extend or implement `num`. assert(value is int || value is double); if (value is double) { - return FieldValuePlatform._(FieldValueType.incrementDouble, value); + return FieldValuePlatform(FieldValueType.incrementDouble, value); } else if (value is int) { - return FieldValuePlatform._(FieldValueType.incrementInteger, value); + return FieldValuePlatform(FieldValueType.incrementInteger, value); } return null; } @override FieldValuePlatform serverTimestamp() => - FieldValuePlatform._(FieldValueType.serverTimestamp, null); + FieldValuePlatform(FieldValueType.serverTimestamp, null); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index 112d3b04d0c2..72a36cc7bc45 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -16,7 +16,7 @@ class WriteBatch extends WriteBatchPlatform { : _handle = MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#create', {'app': _firestore.app.name}), - super._(); + super(); final FirestorePlatform _firestore; Future _handle; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index a94896f3c236..444d2b4c1aab 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -47,7 +47,7 @@ class FieldValuePlatform extends PlatformInterface implements FieldValueInterfac PlatformInterface.verifyToken(instance, _token); } - FieldValuePlatform._(this.type, this.value) : super(token: _token); + FieldValuePlatform(this.type, this.value) : super(token: _token); @override FieldValueInterface get instance => this; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index cf216930a85d..d27a30b0dcf5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -33,7 +33,7 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// Sets the default instance of [FieldValueFactoryPlatform] which is used to build /// [FieldValuePlatform] items static set instance(FieldValueFactoryPlatform instance) { - PlatformInterface.verifyToken(instance, _token); + // PlatformInterface.verifyToken(instance, _token); _instance = instance; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 3a06672b7536..fe852f36c5d3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -31,7 +31,9 @@ abstract class QueryPlatform extends PlatformInterface { /// the object in which it's going to delegate calls has been /// constructed properly. static verifyExtends(QueryPlatform instance) { - PlatformInterface.verifyToken(instance, _token); + if (instance is! CollectionReferencePlatform) { + PlatformInterface.verifyToken(instance, _token); + } } /// The Firestore instance associated with this query diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index 823afae8c560..cc9c3b0e6b23 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -11,7 +11,8 @@ part of cloud_firestore_platform_interface; /// Once committed, no further operations can be performed on the [WriteBatch], /// nor can it be committed again. abstract class WriteBatchPlatform extends PlatformInterface { - WriteBatchPlatform._() : super(token: _token); + /// Overridable constructor + WriteBatchPlatform() : super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart index 4809aedf9008..d28f3de531ae 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; /// Web implementation for Firestore [CollectionReferencePlatform] -class CollectionReferenceWeb implements CollectionReferencePlatform { +class CollectionReferenceWeb extends CollectionReferencePlatform { /// instance of Firestore from the web plugin final web.Firestore webFirestore; final FirestorePlatform _firestorePlatform; @@ -15,7 +15,8 @@ class CollectionReferenceWeb implements CollectionReferencePlatform { CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), - webFirestore.collection(pathComponents.join("/"))); + webFirestore.collection(pathComponents.join("/")),), + super(_firestorePlatform, pathComponents); @override DocumentReferencePlatform parent() { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index d2ff554d76e2..55537206806d 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -2,7 +2,7 @@ part of cloud_firestore_web; /// An implementation of [FieldValueFactoryPlatform] which builds [FieldValuePlatform] /// instance that is [jsify] friendly -class FieldValueFactoryWeb implements FieldValueFactoryPlatform { +class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override FieldValueInterface arrayRemove(List elements) { final delegate = web.FieldValue.arrayRemove(elements); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index 1f627f2396b2..98224ada9892 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -2,10 +2,10 @@ part of cloud_firestore_web; /// Implementation of [FieldValuePlatform] that is compatible with /// firestore web plugin -class FieldValueWeb implements FieldValueInterface, web.FieldValue { +class FieldValueWeb extends FieldValuePlatform implements web.FieldValue { web.FieldValue _delegate; - FieldValueWeb._(this._delegate, this.type, this.value); + FieldValueWeb._(this._delegate, this.type, this.value) : super(type, value); @override final FieldValueType type; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart index e7f84ea6fcbb..9d9c3580f130 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; /// Web implementation for firestore [QueryPlatform] -class QueryWeb implements QueryPlatform { +class QueryWeb extends QueryPlatform { final web.Query _webQuery; final FirestorePlatform _firestore; final bool _isCollectionGroup; @@ -16,7 +16,8 @@ class QueryWeb implements QueryPlatform { QueryWeb(this._firestore, this._path, this._webQuery, {bool isCollectionGroup, List orderByKeys}) : this._isCollectionGroup = isCollectionGroup ?? false, - this._orderByKeys = orderByKeys ?? []; + this._orderByKeys = orderByKeys ?? [], + super(firestore: _firestore, pathComponents: _path.split('/'), isCollectionGroup: isCollectionGroup,); @override Stream snapshots({bool includeMetadataChanges = false}) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart index dc43b72625b4..334691299894 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart @@ -1,14 +1,16 @@ part of cloud_firestore_web; /// A web specific for [Transaction] -class TransactionWeb implements TransactionPlatform { +class TransactionWeb extends TransactionPlatform { final web.Transaction _webTransaction; @override FirestorePlatform firestore; + static int _transactionId = 0; + // ignore: public_member_api_docs @visibleForTesting - TransactionWeb(this._webTransaction, this.firestore); + TransactionWeb(this._webTransaction, this.firestore) : super(_transactionId++, firestore); @override Future delete(DocumentReferencePlatform documentReference) async { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart index 6cbcdfcc6f27..ea5d43aed969 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart @@ -1,7 +1,7 @@ part of cloud_firestore_web; /// A web specific for [WriteBatch] -class WriteBatchWeb implements WriteBatchPlatform { +class WriteBatchWeb extends WriteBatchPlatform { final web.WriteBatch _delegate; // ignore: public_member_api_docs From 3214bb172b04e8eb85930d1af2346bd84b759922 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Thu, 30 Jan 2020 11:54:07 -0800 Subject: [PATCH 114/144] Remove unneeded mocking on app.name so web tests pass again. --- .../cloud_firestore_web/test/transaction_web_test.dart | 1 - .../cloud_firestore_web/test/write_batch_web_test.dart | 2 -- 2 files changed, 3 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index 1c6b350d051f..7f45b7d86e42 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -13,7 +13,6 @@ void main() { final transaction = TransactionWeb(mockWebTransaction, mockFirestore); setUp(() { - when(mockFirestore.app.name).thenReturn("test"); when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart index bed4078bc5ca..3c687a3e90e0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -10,11 +10,9 @@ void main() { final mockWebTransaction = MockWebWriteBatch(); final mockWebDocumentReference = MockWebDocumentReference(); final mockDocumentReference = MockDocumentReference(); - final mockFirestore = MockFirestore(); final transaction = WriteBatchWeb(mockWebTransaction); setUp(() { - when(mockFirestore.app.name).thenReturn("test"); when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); }); From 8a1e1c82f972f7bda709f76778029b70c139004d Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Thu, 30 Jan 2020 13:02:43 -0800 Subject: [PATCH 115/144] Add token verification to instances of FieldValueFactoryPlatform. (Needed a noop constructor to call super with the private _token) --- .../lib/src/platform_interface/field_value_factory.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index d27a30b0dcf5..37ca7f213724 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -25,6 +25,9 @@ enum FieldValueType { /// An interface for a factory that is used to build [FieldValuePlatform] according to /// Platform (web or mobile) abstract class FieldValueFactoryPlatform extends PlatformInterface { + /// Constructor to initialize the PlatformInterface base class + FieldValueFactoryPlatform() : super(token: _token); + /// Current instance of [FieldValueFactoryPlatform] static FieldValueFactoryPlatform get instance => _instance; @@ -33,7 +36,7 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// Sets the default instance of [FieldValueFactoryPlatform] which is used to build /// [FieldValuePlatform] items static set instance(FieldValueFactoryPlatform instance) { - // PlatformInterface.verifyToken(instance, _token); + PlatformInterface.verifyToken(instance, _token); _instance = instance; } From f68b5ea35057b2b18ecae7e3a67ae437f828ae84 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 31 Jan 2020 12:55:23 -0800 Subject: [PATCH 116/144] Use FieldValuePlatform instead of FieldValueInterface. Ensure it's "extended". --- .../cloud_firestore/lib/src/field_value.dart | 4 ++-- .../src/platform_interface/field_value.dart | 3 ++- .../field_value_factory.dart | 10 +++++----- .../lib/src/utils/firestore_message_codec.dart | 2 +- .../test/field_value_test.dart | 2 +- .../method_channel_document_reference.dart | 4 ++-- .../test/transaction_test.dart | 2 +- .../lib/field_value_factory_web.dart | 10 +++++----- .../lib/field_value_web.dart | 2 +- .../lib/utils/codec_utility.dart | 2 +- .../test/codec_utility_test.dart | 18 +++++++++--------- 11 files changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 0b7486037909..20a99c9558d8 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -6,7 +6,7 @@ part of cloud_firestore; /// Sentinel values that can be used when writing document fields with set() or /// update(). -class FieldValue implements platform.FieldValueInterface { +class FieldValue implements platform.FieldValuePlatform { platform.FieldValuePlatform _delegate; FieldValue._(this._delegate) { @@ -14,7 +14,7 @@ class FieldValue implements platform.FieldValueInterface { } @override - platform.FieldValueInterface get instance => _delegate; + platform.FieldValuePlatform get instance => _delegate; @visibleForTesting platform.FieldValueType get type => _delegate.type; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 444d2b4c1aab..056848fff296 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -47,10 +47,11 @@ class FieldValuePlatform extends PlatformInterface implements FieldValueInterfac PlatformInterface.verifyToken(instance, _token); } + /// Constructor FieldValuePlatform(this.type, this.value) : super(token: _token); @override - FieldValueInterface get instance => this; + FieldValuePlatform get instance => this; @override final FieldValueType type; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 37ca7f213724..700d7e20c5ce 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -58,7 +58,7 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// added to the end. If the field being modified is not already an array it /// will be overwritten with an array containing exactly the specified /// elements. - FieldValueInterface arrayUnion(List elements) { + FieldValuePlatform arrayUnion(List elements) { throw UnimplementedError("arrayUnion() is not implemented"); } @@ -68,24 +68,24 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// All instances of each element specified will be removed from the array. /// If the field being modified is not already an array it will be overwritten /// with an empty array. - FieldValueInterface arrayRemove(List elements) { + FieldValuePlatform arrayRemove(List elements) { throw UnimplementedError("arrayRemove() is not implemented"); } /// Returns a sentinel for use with update() to mark a field for deletion. - FieldValueInterface delete() { + FieldValuePlatform delete() { throw UnimplementedError("delete() is not implemented"); } /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. - FieldValueInterface serverTimestamp() { + FieldValuePlatform serverTimestamp() { throw UnimplementedError("serverTimestamp() is not implemented"); } /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - FieldValueInterface increment(num value) { + FieldValuePlatform increment(num value) { throw UnimplementedError("increment() is not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart index 747673040944..224ce849fc80 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart @@ -66,7 +66,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putUint8(_kBlob); writeSize(buffer, value.bytes.length); buffer.putUint8List(value.bytes); - } else if (value is FieldValueInterface) { + } else if (value is FieldValuePlatform) { final int code = _kFieldValueCodes[value.type]; assert(code != null); buffer.putUint8(code); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart index 0dd1fc3f7f02..021d8f208b41 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -2,7 +2,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -class MockFieldValue extends Mock implements FieldValueInterface {} +class MockFieldValue extends Mock implements FieldValuePlatform {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index dab2f1e596a9..6779f4d34f86 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -4,7 +4,7 @@ import 'package:mockito/mockito.dart'; import 'test_common.dart'; -class MockFiledValue extends Mock implements FieldValueInterface {} +class MockFiledValue extends Mock implements FieldValuePlatform {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -105,7 +105,7 @@ void _assertGetMethodCalled(DocumentReferencePlatform documentReference, Source } void _assertSetDataMethodCalled(DocumentReferencePlatform documentReference, - bool expectedMergeValue, FieldValueInterface fieldValue) async { + bool expectedMergeValue, FieldValuePlatform fieldValue) async { bool isMethodCalled = false; final Map data = {"test": "test"}; if (fieldValue != null) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 6ea6ad5f3fd8..539ad8d586a9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -6,7 +6,7 @@ import 'test_common.dart'; class MockDocumentReference extends Mock implements DocumentReferencePlatform {} -class MockFiledValue extends Mock implements FieldValueInterface {} +class MockFiledValue extends Mock implements FieldValuePlatform {} const _kTransactionId = 1022; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart index 55537206806d..e5dd71d02573 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart @@ -4,25 +4,25 @@ part of cloud_firestore_web; /// instance that is [jsify] friendly class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override - FieldValueInterface arrayRemove(List elements) { + FieldValuePlatform arrayRemove(List elements) { final delegate = web.FieldValue.arrayRemove(elements); return FieldValueWeb._(delegate, FieldValueType.arrayRemove, elements); } @override - FieldValueInterface arrayUnion(List elements) { + FieldValuePlatform arrayUnion(List elements) { final delegate = web.FieldValue.arrayUnion(elements); return FieldValueWeb._(delegate, FieldValueType.arrayUnion, elements); } @override - FieldValueInterface delete() { + FieldValuePlatform delete() { final delegate = web.FieldValue.delete(); return FieldValueWeb._(delegate, FieldValueType.delete, null); } @override - FieldValueInterface increment(num value) { + FieldValuePlatform increment(num value) { assert(value is double || value is int, "value can only be double or int"); final delegate = web.FieldValue.increment(value); return FieldValueWeb._( @@ -34,7 +34,7 @@ class FieldValueFactoryWeb extends FieldValueFactoryPlatform { } @override - FieldValueInterface serverTimestamp() { + FieldValuePlatform serverTimestamp() { final delegate = web.FieldValue.serverTimestamp(); return FieldValueWeb._(delegate, FieldValueType.serverTimestamp, null); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart index 98224ada9892..4738d7fd3859 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart @@ -14,5 +14,5 @@ class FieldValueWeb extends FieldValuePlatform implements web.FieldValue { final dynamic value; @override - FieldValueInterface get instance => this; + FieldValuePlatform get instance => this; } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart index 9280029ef062..2ffedddd5e8f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart @@ -30,7 +30,7 @@ class CodecUtility { @visibleForTesting // ignore: public_member_api_docs static dynamic valueEncode(dynamic value) { - if (value is FieldValueInterface && value.instance is FieldValueWeb) { + if (value is FieldValuePlatform && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb)._delegate; } else if (value is Timestamp) { return value.toDate(); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index 5754930761d9..94fed125b797 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -7,7 +7,7 @@ import 'package:mockito/mockito.dart'; import 'dart:js' as js; import 'package:firebase/firestore.dart' as web; -class MockFieldValueInterface extends Mock implements FieldValueInterface {} +class MockFieldValue extends Mock implements FieldValuePlatform {} class MockGeoPoint extends Mock implements GeoPoint {} @@ -35,10 +35,10 @@ void main() { test("encodeMapData", () { expect(CodecUtility.encodeMapData(null), isNull); - //FieldValueInterface - final mockFieldValueInterface = MockFieldValueInterface(); - CodecUtility.encodeMapData({'test': mockFieldValueInterface}); - verify(mockFieldValueInterface.instance); + //FieldValuePlatform + final mockFieldValue = MockFieldValue(); + CodecUtility.encodeMapData({'test': mockFieldValue}); + verify(mockFieldValue.instance); final timeStamp = Timestamp.now(); final result = CodecUtility.encodeMapData({'test': timeStamp}); @@ -78,10 +78,10 @@ void main() { test("encodeArrayData", () { expect(CodecUtility.encodeArrayData(null), isNull); - //FieldValueInterface - final mockFieldValueInterface = MockFieldValueInterface(); - CodecUtility.encodeArrayData([mockFieldValueInterface]); - verify(mockFieldValueInterface.instance); + //FieldValuePlatform + final mockFieldValue = MockFieldValue(); + CodecUtility.encodeArrayData([mockFieldValue]); + verify(mockFieldValue.instance); final timeStamp = Timestamp.now(); final result = CodecUtility.encodeArrayData([timeStamp]); From 6f4d042bb880d6e737fa125e11a23394dd7d4fa0 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 31 Jan 2020 16:24:27 -0800 Subject: [PATCH 117/144] Docs update --- .../lib/src/field_path.dart | 3 +-- .../method_channel_collection_reference.dart | 11 +++++------ .../method_channel_document_reference.dart | 5 +++-- .../lib/src/platform_interface/document_change.dart | 1 + .../src/platform_interface/document_reference.dart | 5 +++-- .../lib/src/platform_interface/field_value.dart | 1 + .../src/platform_interface/field_value_factory.dart | 1 + .../lib/src/platform_interface/query.dart | 1 + .../lib/src/platform_interface/query_snapshot.dart | 1 + .../lib/src/platform_interface/transaction.dart | 1 + 10 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index c2b6ec47b307..ae3146e03a7f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -12,8 +12,7 @@ enum _FieldPathType { class FieldPath { const FieldPath._(this.type); - /// The type of this FieldPath - /// (Used in the [FirestoreMessageCodec]) + /// The type of this field path (used in [FirestoreMessageCodec]) final _FieldPathType type; /// The path to the document id, which can be used in queries. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index d7d1276f21dd..1d7f502df976 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -8,12 +8,11 @@ part of cloud_firestore_platform_interface; /// document references, and querying for documents (using the methods /// inherited from [QueryPlatform]). /// -/// Note that this class *should* extend CollectionReferencePlatform, but -/// it doesn't because of the extensive changes required to MethodChannelQuery -/// (which *does* extend its Platform class). -/// -/// If you changed CollectionReferencePlatform and this class started throwing -/// compilation errors, now you know why it is. +/// Note that this class *should* extend [CollectionReferencePlatform], but +/// it doesn't because of the extensive changes required to [MethodChannelQuery] +/// (which *does* extend its Platform class). If you changed +/// [CollectionReferencePlatform] and this class started throwing compilation +/// errors, now you know why. class MethodChannelCollectionReference extends MethodChannelQuery implements CollectionReferencePlatform { /// Create a [MethodChannelCollectionReference] from [pathComponents] diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 316fe50f6f6b..03a7f293723d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -4,8 +4,9 @@ part of cloud_firestore_platform_interface; -/// A [MethodChannelDocumentReference] is an implementation of [DocumentReferencePlatform] -/// that uses [MethodChannel] to communicate with Firebase plugins +/// A [MethodChannelDocumentReference] is an implementation of +/// [DocumentReferencePlatform] that uses [MethodChannel] to communicate with +/// Firebase plugins. class MethodChannelDocumentReference extends DocumentReferencePlatform { /// Creates a [DocumentReferencePlatform] that is implemented using [MethodChannel]. MethodChannelDocumentReference( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index b083f7529eed..53c3bc24989f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -30,6 +30,7 @@ class DocumentChangePlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [DocumentChangePlatform]. + /// /// This is used by the app-facing [DocumentChange] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 81694c57c5ba..814adf3637f8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -4,8 +4,8 @@ part of cloud_firestore_platform_interface; /// and can be used to write, read, or listen to the location. /// /// The document at the referenced location may or may not exist. -/// A [DocumentReferencePlatform] can also be used to create a [CollectionReferencePlatform] -/// to a subcollection. +/// A [DocumentReferencePlatform] can also be used to create a +/// [CollectionReferencePlatform] to a subcollection. abstract class DocumentReferencePlatform extends PlatformInterface { /// Create instance of [DocumentReferencePlatform] DocumentReferencePlatform(this.firestore, this._pathComponents) : super(token: _token); @@ -14,6 +14,7 @@ abstract class DocumentReferencePlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [DocumentReferencePlatform]. + /// /// This is used by the app-facing [DocumentReference] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 056848fff296..c1226a5cb00f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -40,6 +40,7 @@ class FieldValuePlatform extends PlatformInterface implements FieldValueInterfac /// Throws an [AssertionError] if [instance] does not extend /// [FieldValuePlatform]. + /// /// This is used by the app-facing [FieldValue] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 700d7e20c5ce..9ebce5991ffb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -44,6 +44,7 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [FieldValueFactoryPlatform]. + /// /// This is used by the app-facing [FieldValueFactory] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index fe852f36c5d3..c3d895acdca9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -27,6 +27,7 @@ abstract class QueryPlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [QueryPlatform]. + /// /// This is used by the app-facing [Query] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 5fec024d6bdf..ccfc000acb71 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -13,6 +13,7 @@ class QuerySnapshotPlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [QuerySnapshotPlatform]. + /// /// This is used by the app-facing [QuerySnapshot] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index a2a61f240fc6..99a0af7fe927 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -19,6 +19,7 @@ abstract class TransactionPlatform extends PlatformInterface { /// Throws an [AssertionError] if [instance] does not extend /// [TransactionPlatform]. + /// /// This is used by the app-facing [Transaction] to ensure that /// the object in which it's going to delegate calls has been /// constructed properly. From 9dcc1c99516ad47957de0fbf014af15410ef8296 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 31 Jan 2020 17:08:07 -0800 Subject: [PATCH 118/144] Hide most of the API surface from cloud_firestore_web. Convert the library into an import-based one, instead of a part-based one. --- .../lib/field_value_web.dart | 18 ---------------- .../lib/firestore_web.dart | 20 ++++++------------ .../{ => src}/collection_reference_web.dart | 7 ++++++- .../lib/{ => src}/document_reference_web.dart | 11 +++++++--- .../{ => src}/field_value_factory_web.dart | 16 ++++++++------ .../lib/src/field_value_web.dart | 21 +++++++++++++++++++ .../lib/{ => src}/query_web.dart | 10 ++++++--- .../lib/{ => src}/transaction_web.dart | 13 ++++++++---- .../lib/{ => src}/utils/codec_utility.dart | 14 +++++++------ .../utils/document_reference_utils.dart | 7 +++++-- .../lib/{ => src}/write_batch_web.dart | 10 ++++++--- .../test/codec_utility_test.dart | 4 +++- .../test/collection_reference_web_test.dart | 3 ++- .../test/document_reference_web_test.dart | 2 +- .../test/field_value_factory_web_test.dart | 3 ++- .../test/query_web_test.dart | 1 + .../cloud_firestore_web/test/test_common.dart | 3 +++ .../test/transaction_web_test.dart | 2 +- .../test/write_batch_web_test.dart | 2 +- 19 files changed, 101 insertions(+), 66 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/collection_reference_web.dart (94%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/document_reference_web.dart (76%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/field_value_factory_web.dart (64%) create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/query_web.dart (95%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/transaction_web.dart (76%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/utils/codec_utility.dart (86%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/utils/document_reference_utils.dart (58%) rename packages/cloud_firestore/cloud_firestore_web/lib/{ => src}/write_batch_web.dart (75%) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart deleted file mode 100644 index 4738d7fd3859..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_web.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of cloud_firestore_web; - -/// Implementation of [FieldValuePlatform] that is compatible with -/// firestore web plugin -class FieldValueWeb extends FieldValuePlatform implements web.FieldValue { - web.FieldValue _delegate; - - FieldValueWeb._(this._delegate, this.type, this.value) : super(type, value); - - @override - final FieldValueType type; - - @override - final dynamic value; - - @override - FieldValuePlatform get instance => this; -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index b45a468d20f5..e279ddf2d546 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -1,23 +1,15 @@ -library cloud_firestore_web; - import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:js/js_util.dart'; -import 'package:meta/meta.dart'; -part 'collection_reference_web.dart'; -part 'utils/codec_utility.dart'; -part 'utils/document_reference_utils.dart'; -part 'field_value_factory_web.dart'; -part 'document_reference_web.dart'; -part 'query_web.dart'; -part 'transaction_web.dart'; -part 'field_value_web.dart'; -part 'write_batch_web.dart'; +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; +import 'package:cloud_firestore_web/src/transaction_web.dart'; +import 'package:cloud_firestore_web/src/write_batch_web.dart'; /// Web implementation for [FirestorePlatform] /// delegates calls to firestore web plugin diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart similarity index 94% rename from packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index d28f3de531ae..a68da59dbc05 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -1,4 +1,9 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; /// Web implementation for Firestore [CollectionReferencePlatform] class CollectionReferenceWeb extends CollectionReferencePlatform { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart similarity index 76% rename from packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart index 72e640b18a66..8ac651273bf9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -1,4 +1,9 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; /// Web implementation for firestore [DocumentReferencePlatform] class DocumentReferenceWeb extends DocumentReferencePlatform { @@ -26,7 +31,7 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { @override Future get({Source source = Source.serverAndCache}) async { - return _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + return fromWebDocumentSnapshotToPlatformDocumentSnapshot( await delegate.get(), this.firestore); } @@ -40,7 +45,7 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { querySnapshots = delegate.onMetadataChangesSnapshot; } return querySnapshots.map((webSnapshot) => - _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + fromWebDocumentSnapshotToPlatformDocumentSnapshot( webSnapshot, this.firestore)); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart similarity index 64% rename from packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart index e5dd71d02573..3ece3185fcf4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart @@ -1,4 +1,8 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:js/js_util.dart'; + +import 'package:cloud_firestore_web/src/field_value_web.dart'; /// An implementation of [FieldValueFactoryPlatform] which builds [FieldValuePlatform] /// instance that is [jsify] friendly @@ -6,26 +10,26 @@ class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override FieldValuePlatform arrayRemove(List elements) { final delegate = web.FieldValue.arrayRemove(elements); - return FieldValueWeb._(delegate, FieldValueType.arrayRemove, elements); + return FieldValueWeb(delegate, FieldValueType.arrayRemove, elements); } @override FieldValuePlatform arrayUnion(List elements) { final delegate = web.FieldValue.arrayUnion(elements); - return FieldValueWeb._(delegate, FieldValueType.arrayUnion, elements); + return FieldValueWeb(delegate, FieldValueType.arrayUnion, elements); } @override FieldValuePlatform delete() { final delegate = web.FieldValue.delete(); - return FieldValueWeb._(delegate, FieldValueType.delete, null); + return FieldValueWeb(delegate, FieldValueType.delete, null); } @override FieldValuePlatform increment(num value) { assert(value is double || value is int, "value can only be double or int"); final delegate = web.FieldValue.increment(value); - return FieldValueWeb._( + return FieldValueWeb( delegate, value is int ? FieldValueType.incrementInteger @@ -36,6 +40,6 @@ class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override FieldValuePlatform serverTimestamp() { final delegate = web.FieldValue.serverTimestamp(); - return FieldValueWeb._(delegate, FieldValueType.serverTimestamp, null); + return FieldValueWeb(delegate, FieldValueType.serverTimestamp, null); } } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart new file mode 100644 index 000000000000..92d097dfb607 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -0,0 +1,21 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +/// Implementation of [FieldValuePlatform] that is compatible with +/// firestore web plugin +class FieldValueWeb extends FieldValuePlatform implements web.FieldValue { + /// The js-interop delegate for this [FieldValuePlatform] + web.FieldValue delegate; + + /// Constructor. + FieldValueWeb(this.delegate, this.type, this.value) : super(type, value); + + @override + final FieldValueType type; + + @override + final dynamic value; + + @override + FieldValuePlatform get instance => this; +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart similarity index 95% rename from packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index 9d9c3580f130..15d1ab075fe5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -1,4 +1,8 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; /// Web implementation for firestore [QueryPlatform] class QueryWeb extends QueryPlatform { @@ -216,7 +220,7 @@ class QueryWeb extends QueryPlatform { return QuerySnapshotPlatform( webSnapshot.docs .map((webSnapshot) => - _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + fromWebDocumentSnapshotToPlatformDocumentSnapshot( webSnapshot, this._firestore)) .toList(), webSnapshot.docChanges().map(_webChangeToChange).toList(), @@ -228,7 +232,7 @@ class QueryWeb extends QueryPlatform { _fromString(webChange.type), webChange.oldIndex, webChange.newIndex, - _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + fromWebDocumentSnapshotToPlatformDocumentSnapshot( webChange.doc, this._firestore)); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart similarity index 76% rename from packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 334691299894..87566543d9f2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -1,4 +1,10 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; /// A web specific for [Transaction] class TransactionWeb extends TransactionPlatform { @@ -8,8 +14,7 @@ class TransactionWeb extends TransactionPlatform { static int _transactionId = 0; - // ignore: public_member_api_docs - @visibleForTesting + /// Constructor. TransactionWeb(this._webTransaction, this.firestore) : super(_transactionId++, firestore); @override @@ -24,7 +29,7 @@ class TransactionWeb extends TransactionPlatform { assert(documentReference is DocumentReferenceWeb); final webSnapshot = await _webTransaction .get((documentReference as DocumentReferenceWeb).delegate); - return _fromWebDocumentSnapshotToPlatformDocumentSnapshot( + return fromWebDocumentSnapshotToPlatformDocumentSnapshot( webSnapshot, this.firestore); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart similarity index 86% rename from packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index 2ffedddd5e8f..22cc66ef9651 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -1,11 +1,13 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/field_value_web.dart'; -// disabling lint as it's only visible for testing -@visibleForTesting // ignore: public_member_api_docs class CodecUtility { - // disabling lint as it's only visible for testing - @visibleForTesting // ignore: public_member_api_docs static Map encodeMapData(Map data) { if (data == null) { @@ -31,7 +33,7 @@ class CodecUtility { // ignore: public_member_api_docs static dynamic valueEncode(dynamic value) { if (value is FieldValuePlatform && value.instance is FieldValueWeb) { - return (value.instance as FieldValueWeb)._delegate; + return (value.instance as FieldValueWeb).delegate; } else if (value is Timestamp) { return value.toDate(); } else if (value is GeoPoint) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart similarity index 58% rename from packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart index 1282a390da18..95f9429452e2 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/utils/document_reference_utils.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart @@ -1,7 +1,10 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; /// Builds [DocumentSnapshot] instance form web snapshot instance -DocumentSnapshot _fromWebDocumentSnapshotToPlatformDocumentSnapshot( +DocumentSnapshot fromWebDocumentSnapshotToPlatformDocumentSnapshot( web.DocumentSnapshot webSnapshot, FirestorePlatform firestore) { return DocumentSnapshot( webSnapshot.ref.path, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart similarity index 75% rename from packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart index ea5d43aed969..2ad55f9c37d5 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart @@ -1,11 +1,15 @@ -part of cloud_firestore_web; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; /// A web specific for [WriteBatch] class WriteBatchWeb extends WriteBatchPlatform { final web.WriteBatch _delegate; - // ignore: public_member_api_docs - @visibleForTesting + /// Constructor. WriteBatchWeb(this._delegate); @override diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index 94fed125b797..a3e01fc3d8b0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -1,12 +1,14 @@ @TestOn("chrome") import 'dart:typed_data'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'dart:js' as js; import 'package:firebase/firestore.dart' as web; +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; + class MockFieldValue extends Mock implements FieldValuePlatform {} class MockGeoPoint extends Mock implements GeoPoint {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index fe86fccf42f5..d139cb6cdf05 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -2,7 +2,8 @@ import 'dart:js' as js; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'test_common.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart index 91513296e2d9..65cc64f72905 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -1,6 +1,6 @@ @TestOn('chrome') import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart index d4c18f33301d..8535616d05ed 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -1,6 +1,7 @@ @TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; +import 'package:cloud_firestore_web/src/field_value_web.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index f3b52c2ff779..0bd03b0e32ff 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -4,6 +4,7 @@ import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:firebase/firestore.dart' as web; +import 'package:cloud_firestore_web/src/query_web.dart'; import 'test_common.dart'; class MockWebQuery extends Mock implements web.Query {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 967ed27a9994..3a76de40ac4f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -6,6 +6,9 @@ import 'package:firebase_core_web/firebase_core_web.dart'; import 'package:mockito/mockito.dart'; import 'package:firebase/firestore.dart' as web; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; + const kCollectionId = "test"; class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index 7f45b7d86e42..2268bc027044 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -1,5 +1,5 @@ @TestOn("chrome") -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/transaction_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'test_common.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart index 3c687a3e90e0..e6ed15ecff94 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -1,6 +1,6 @@ @TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/write_batch_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'test_common.dart'; From 8b95bc9e939bc1c587619fd7e2d49f98732ab9c6 Mon Sep 17 00:00:00 2001 From: Collin Jackson Date: Fri, 31 Jan 2020 17:19:07 -0800 Subject: [PATCH 119/144] Hide _webFirestore --- .../lib/firestore_web.dart | 22 +++++++++---------- .../lib/src/utils/codec_utility.dart | 5 +---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index e279ddf2d546..bd1d61094b2c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -15,7 +15,7 @@ import 'package:cloud_firestore_web/src/write_batch_web.dart'; /// delegates calls to firestore web plugin class FirestoreWeb extends FirestorePlatform { /// instance of Firestore from the web plugin - final Firestore webFirestore; + final Firestore _webFirestore; /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { @@ -25,7 +25,7 @@ class FirestoreWeb extends FirestorePlatform { /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance /// If [app] is null then the created instance will use the default [FirebaseApp] FirestoreWeb({FirebaseApp app}) - : webFirestore = firebase + : _webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), super(app: app ?? FirebaseApp.instance) { FieldValueFactoryPlatform.instance = FieldValueFactoryWeb(); @@ -36,26 +36,26 @@ class FirestoreWeb extends FirestorePlatform { @override CollectionReferencePlatform collection(String path) { - return CollectionReferenceWeb(this, webFirestore, path.split('/')); + return CollectionReferenceWeb(this, _webFirestore, path.split('/')); } @override QueryPlatform collectionGroup(String path) { - return QueryWeb(this, path, webFirestore.collectionGroup(path), + return QueryWeb(this, path, _webFirestore.collectionGroup(path), isCollectionGroup: true); } @override DocumentReferencePlatform document(String path) => - DocumentReferenceWeb(webFirestore, this, path.split('/')); + DocumentReferenceWeb(_webFirestore, this, path.split('/')); @override - WriteBatchPlatform batch() => WriteBatchWeb(webFirestore.batch()); + WriteBatchPlatform batch() => WriteBatchWeb(_webFirestore.batch()); @override Future enablePersistence(bool enable) async { if (enable) { - await webFirestore.enablePersistence(); + await _webFirestore.enablePersistence(); } } @@ -66,16 +66,16 @@ class FirestoreWeb extends FirestorePlatform { bool sslEnabled, int cacheSizeBytes}) async { if (host != null && sslEnabled != null) { - webFirestore.settings(Settings( + _webFirestore.settings(Settings( cacheSizeBytes: cacheSizeBytes ?? 40000000, host: host, ssl: sslEnabled)); } else { - webFirestore + _webFirestore .settings(Settings(cacheSizeBytes: cacheSizeBytes ?? 40000000)); } if (persistenceEnabled) { - await webFirestore.enablePersistence(); + await _webFirestore.enablePersistence(); } } @@ -84,7 +84,7 @@ class FirestoreWeb extends FirestorePlatform { TransactionHandler transactionHandler, {Duration timeout = const Duration(seconds: 5)}) async { Map result; - await webFirestore.runTransaction((transaction) async { + await _webFirestore.runTransaction((transaction) async { result = await transactionHandler(TransactionWeb(transaction, this)); }).timeout(timeout); return result is Map ? result : {}; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index 22cc66ef9651..f05703b20f1c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -83,10 +83,7 @@ class CodecUtility { } else if (value is web.Blob) { return Blob(value.toUint8Array()); } else if (value is web.DocumentReference) { - return DocumentReferenceWeb( - (FirestorePlatform.instance as FirestoreWeb).webFirestore, - FirestorePlatform.instance, - value.path.split("/")); + return (FirestorePlatform.instance as FirestoreWeb).document(value.path); } else if (value is Map) { return decodeMapData(value); } else if (value is List) { From b7b5fc994ae39948569e2080b8ccff115b79469b Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 31 Jan 2020 17:46:40 -0800 Subject: [PATCH 120/144] Moving some more stuff around --- .../cloud_firestore/lib/cloud_firestore.dart | 13 ------- .../lib/src/utils/auto_id_generator.dart | 34 ------------------- .../cloud_firestore_platform_interface.dart | 2 +- .../utils/firestore_message_codec.dart | 0 4 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/utils/auto_id_generator.dart rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/utils/firestore_message_codec.dart (100%) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index da795fb0945e..72180140f61e 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -18,29 +18,16 @@ export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte show FieldPath, Blob, GeoPoint, Timestamp; part 'src/collection_reference.dart'; - part 'src/document_change.dart'; - part 'src/utils/platform_utils.dart'; - part 'src/document_reference.dart'; - part 'src/document_snapshot.dart'; - part 'src/field_value.dart'; - part 'src/firestore.dart'; - part 'src/query.dart'; - part 'src/query_snapshot.dart'; - part 'src/utils/codec_utility.dart'; - part 'src/snapshot_metadata.dart'; - part 'src/transaction.dart'; - part 'src/write_batch.dart'; - part 'src/source.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/auto_id_generator.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/auto_id_generator.dart deleted file mode 100644 index e2e1cc57138a..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/auto_id_generator.dart +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. 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:math'; - -/// Utility class for generating Firebase child node keys. -/// -/// Since the Flutter plugin API is asynchronous, there's no way for us -/// to use the native SDK to generate the node key synchronously and we -/// have to do it ourselves if we want to be able to reference the -/// newly-created node synchronously. -/// -/// This code is based largely on the Android implementation and ported to Dart. - -class AutoIdGenerator { - static const int _AUTO_ID_LENGTH = 20; - - static const String _AUTO_ID_ALPHABET = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - static final Random _random = Random(); - - static String autoId() { - final StringBuffer stringBuffer = StringBuffer(); - final int maxRandom = _AUTO_ID_ALPHABET.length; - - for (int i = 0; i < _AUTO_ID_LENGTH; ++i) { - stringBuffer.write(_AUTO_ID_ALPHABET[_random.nextInt(maxRandom)]); - } - - return stringBuffer.toString(); - } -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 55b9b1a227e2..909cacd702d5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -27,7 +27,7 @@ part 'src/platform_interface/write_batch.dart'; // Method channel parts part 'src/method_channel_firestore.dart'; -part 'src/utils/firestore_message_codec.dart'; +part 'src/method_channel/utils/firestore_message_codec.dart'; part 'src/method_channel/method_channel_collection_reference.dart'; part 'src/method_channel/method_channel_document_change.dart'; part 'src/method_channel/method_channel_document_reference.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/firestore_message_codec.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart From bd96ddeb5b9d1561f72d5a93ff56e0f3a5f15429 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Fri, 31 Jan 2020 19:47:03 -0800 Subject: [PATCH 121/144] Hide the MethodChannel implementation from the world. --- .../cloud_firestore/lib/src/firestore.dart | 3 -- .../cloud_firestore_platform_interface.dart | 18 +-------- .../lib/src/field_path.dart | 8 ++-- .../method_channel_collection_reference.dart | 6 ++- .../method_channel_document_change.dart | 3 +- .../method_channel_document_reference.dart | 13 +++++-- .../method_channel_field_value_factory.dart | 4 +- .../method_channel_firestore.dart | 28 +++++++++---- .../method_channel/method_channel_query.dart | 39 ++++++++++++------- .../method_channel_query_snapshot.dart | 4 +- .../method_channel_transaction.dart | 33 +++++++++------- .../method_channel_write_batch.dart | 19 +++++---- .../utils/firestore_message_codec.dart | 13 +++++-- .../src/{ => method_channel}/utils/maps.dart | 0 .../lib/src/platform_interface/query.dart | 5 ++- .../src/platform_interface/transaction.dart | 39 +++++++++++++------ .../src/platform_interface/write_batch.dart | 3 -- .../lib/src/source.dart | 2 +- .../method_channel_cloud_firestore_test.dart | 17 ++++---- ...hod_channel_collection_reference_test.dart | 3 ++ .../method_channel_document_reference.dart | 2 + ...thod_channel_field_value_factory_test.dart | 2 + .../test/query_test.dart | 2 + .../test/test_common.dart | 2 + .../test/transaction_test.dart | 8 ++-- .../lib/src/transaction_web.dart | 5 +-- .../test/write_batch_web_test.dart | 3 +- 27 files changed, 174 insertions(+), 110 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/method_channel_firestore.dart (81%) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/utils/maps.dart (100%) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart index cf9bd3d64c13..9a85ad6fe17a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/firestore.dart @@ -25,9 +25,6 @@ class Firestore { ? platform.FirestorePlatform.instanceFor(app: app) : platform.FirestorePlatform.instance; - @visibleForTesting - static MethodChannel get channel => platform.MethodChannelFirestore.channel; - /// Gets the instance of Firestore for the default Firebase app. static Firestore get instance => Firestore(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 909cacd702d5..f4a4da5cba55 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -1,19 +1,17 @@ library cloud_firestore_platform_interface; import 'dart:async'; -import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui'; import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'src/utils/maps.dart'; -import 'src/utils/auto_id_generator.dart'; +import 'src/method_channel/method_channel_firestore.dart'; +import 'src/method_channel/method_channel_field_value_factory.dart'; export 'src/utils/auto_id_generator.dart'; @@ -25,18 +23,6 @@ part 'src/platform_interface/document_reference.dart'; part 'src/platform_interface/transaction.dart'; part 'src/platform_interface/write_batch.dart'; -// Method channel parts -part 'src/method_channel_firestore.dart'; -part 'src/method_channel/utils/firestore_message_codec.dart'; -part 'src/method_channel/method_channel_collection_reference.dart'; -part 'src/method_channel/method_channel_document_change.dart'; -part 'src/method_channel/method_channel_document_reference.dart'; -part 'src/method_channel/method_channel_field_value_factory.dart'; -part 'src/method_channel/method_channel_query_snapshot.dart'; -part 'src/method_channel/method_channel_query.dart'; -part 'src/method_channel/method_channel_transaction.dart'; -part 'src/method_channel/method_channel_write_batch.dart'; - // Shared types part 'src/blob.dart'; part 'src/document_snapshot.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index ae3146e03a7f..1d6068159027 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -4,7 +4,9 @@ part of cloud_firestore_platform_interface; -enum _FieldPathType { +/// The types of field paths supported. +enum FieldPathType { + /// Document ID. documentId, } @@ -13,9 +15,9 @@ class FieldPath { const FieldPath._(this.type); /// The type of this field path (used in [FirestoreMessageCodec]) - final _FieldPathType type; + final FieldPathType type; /// The path to the document id, which can be used in queries. static FieldPath get documentId => - const FieldPath._(_FieldPathType.documentId); + const FieldPath._(FieldPathType.documentId); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index 1d7f502df976..b555b561da18 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -1,8 +1,12 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. 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'; -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +import 'method_channel_query.dart'; +import 'method_channel_document_reference.dart'; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart index ca17721f70db..972bd6282ea4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart @@ -1,8 +1,9 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -part of cloud_firestore_platform_interface; +import 'utils/maps.dart'; /// A DocumentChange represents a change to the documents matching a query. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 03a7f293723d..a108a60537a6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -1,8 +1,13 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. 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'; -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter/services.dart'; + +import 'method_channel_firestore.dart'; +import 'utils/maps.dart'; /// A [MethodChannelDocumentReference] is an implementation of /// [DocumentReferencePlatform] that uses [MethodChannel] to communicate with @@ -47,7 +52,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { { 'app': firestore.app.name, 'path': path, - 'source': _getSourceString(source), + 'source': getSourceString(source), }, ); return DocumentSnapshot( @@ -86,7 +91,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { }, ).then((dynamic result) => result); _handle.then((int handle) { - MethodChannelFirestore._documentObservers[handle] = controller; + MethodChannelFirestore.documentObservers[handle] = controller; }); }, onCancel: () { @@ -95,7 +100,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { 'removeListener', {'handle': handle}, ); - MethodChannelFirestore._documentObservers.remove(handle); + MethodChannelFirestore.documentObservers.remove(handle); }); }, ); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 0c0052fe0237..04634cc5a69e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -1,4 +1,6 @@ -part of cloud_firestore_platform_interface; +import 'package:flutter/services.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// An implementation of [FieldValueFactoryPlatform] that is suitable to be used /// on mobile where communication relies on [MethodChannel] diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart similarity index 81% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index d0c493a6e05a..7fda9d6e1993 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -1,8 +1,20 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. 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'; -part of cloud_firestore_platform_interface; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/services.dart'; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +import 'method_channel_collection_reference.dart'; +import 'method_channel_document_reference.dart'; +import 'method_channel_query.dart'; +import 'method_channel_query_snapshot.dart'; +import 'method_channel_transaction.dart'; +import 'method_channel_write_batch.dart'; +import 'utils/firestore_message_codec.dart'; +import 'utils/maps.dart'; /// The entry point for accessing a Firestore. /// @@ -16,7 +28,7 @@ class MethodChannelFirestore extends FirestorePlatform { if (call.method == 'QuerySnapshot') { final QuerySnapshotPlatform snapshot = MethodChannelQuerySnapshot(call.arguments, this); - _queryObservers[call.arguments['handle']].add(snapshot); + queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { final DocumentSnapshot snapshot = DocumentSnapshot( call.arguments['path'], @@ -25,11 +37,11 @@ class MethodChannelFirestore extends FirestorePlatform { call.arguments['metadata']['isFromCache']), this, ); - _documentObservers[call.arguments['handle']].add(snapshot); + documentObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DoTransaction') { final int transactionId = call.arguments['transactionId']; - final Transaction transaction = - Transaction(transactionId, call.arguments["app"]); + final TransactionPlatform transaction = + MethodChannelTransaction(transactionId, call.arguments["app"]); final dynamic result = await _transactionHandlers[transactionId](transaction); await transaction.finish(); @@ -51,10 +63,10 @@ class MethodChannelFirestore extends FirestorePlatform { StandardMethodCodec(FirestoreMessageCodec()), ); - static final Map> _queryObservers = + static final Map> queryObservers = >{}; - static final Map> _documentObservers = + static final Map> documentObservers = >{}; static final Map _transactionHandlers = @@ -89,7 +101,7 @@ class MethodChannelFirestore extends FirestorePlatform { } @override - WriteBatch batch() => WriteBatch(this); + WriteBatchPlatform batch() => MethodChannelWriteBatch(this); @override Future> runTransaction( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index 89f6f82f9aff..2a2e80142026 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -2,7 +2,15 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'dart:async'; + +import 'package:collection/collection.dart'; +import 'package:flutter/foundation.dart'; +import 'package:meta/meta.dart' show required; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +import 'method_channel_firestore.dart'; +import 'method_channel_query_snapshot.dart'; /// Represents a query over the data at a particular location. class MethodChannelQuery extends QueryPlatform { @@ -19,7 +27,8 @@ class MethodChannelQuery extends QueryPlatform { parameters: parameters, ); - QueryPlatform _copyWithParameters(Map parameters) { + @override + QueryPlatform copyWithParameters(Map parameters) { return MethodChannelQuery( firestore: firestore, isCollectionGroup: isCollectionGroup, @@ -51,7 +60,7 @@ class MethodChannelQuery extends QueryPlatform { }, ).then((dynamic result) => result); _handle.then((int handle) { - MethodChannelFirestore._queryObservers[handle] = controller; + MethodChannelFirestore.queryObservers[handle] = controller; }); }, onCancel: () { @@ -60,7 +69,7 @@ class MethodChannelQuery extends QueryPlatform { 'removeListener', {'handle': handle}, ); - MethodChannelFirestore._queryObservers.remove(handle); + MethodChannelFirestore.queryObservers.remove(handle); }); }, ); @@ -79,7 +88,7 @@ class MethodChannelQuery extends QueryPlatform { 'path': path, 'isCollectionGroup': isCollectionGroup, 'parameters': parameters, - 'source': _getSourceString(source), + 'source': getSourceString(source), }, ); return MethodChannelQuerySnapshot(data, firestore); @@ -143,7 +152,7 @@ class MethodChannelQuery extends QueryPlatform { addCondition(field, '==', null); } - return _copyWithParameters({'where': conditions}); + return copyWithParameters({'where': conditions}); } @override @@ -172,7 +181,7 @@ class MethodChannelQuery extends QueryPlatform { 'Hence, you may not use an order by [FieldPath.documentId] when using any of these methods for a query.'); orders.add(order); - return _copyWithParameters({'orderBy': orders}); + return copyWithParameters({'orderBy': orders}); } @override @@ -188,7 +197,7 @@ class MethodChannelQuery extends QueryPlatform { .isEmpty, '[startAfterDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAfterDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'startAfterDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -210,7 +219,7 @@ class MethodChannelQuery extends QueryPlatform { .isEmpty, '[startAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [startAtDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'startAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -226,7 +235,7 @@ class MethodChannelQuery extends QueryPlatform { assert(!parameters.containsKey('startAt')); assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAfter': values}); + return copyWithParameters({'startAfter': values}); } @override @@ -236,7 +245,7 @@ class MethodChannelQuery extends QueryPlatform { assert(!parameters.containsKey('startAt')); assert(!parameters.containsKey('startAfterDocument')); assert(!parameters.containsKey('startAtDocument')); - return _copyWithParameters({'startAt': values}); + return copyWithParameters({'startAt': values}); } @override @@ -253,7 +262,7 @@ class MethodChannelQuery extends QueryPlatform { '[endAtDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endAtDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'endAtDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -269,7 +278,7 @@ class MethodChannelQuery extends QueryPlatform { assert(!parameters.containsKey('endAt')); assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endAt': values}); + return copyWithParameters({'endAt': values}); } @override @@ -285,7 +294,7 @@ class MethodChannelQuery extends QueryPlatform { .isEmpty, '[endBeforeDocument] orders by document id itself. ' 'Hence, you may not use an order by [FieldPath.documentId] when using [endBeforeDocument].'); - return _copyWithParameters({ + return copyWithParameters({ 'endBeforeDocument': { 'id': documentSnapshot.documentID, 'path': documentSnapshot.reference.path, @@ -301,6 +310,6 @@ class MethodChannelQuery extends QueryPlatform { assert(!parameters.containsKey('endAt')); assert(!parameters.containsKey('endBeforeDocument')); assert(!parameters.containsKey('endAtDocument')); - return _copyWithParameters({'endBefore': values}); + return copyWithParameters({'endBefore': values}); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index f41430c4d140..f59c06e1293a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -1,8 +1,10 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -part of cloud_firestore_platform_interface; +import 'method_channel_document_change.dart'; +import 'utils/maps.dart'; /// Contains zero or more [DocumentSnapshot] objects. class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index 8067f623c56f..3b283518a631 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -2,27 +2,34 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'dart:async'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show visibleForTesting; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +import 'method_channel_firestore.dart'; /// An implementation of [TransactionPlatform] which uses [MethodChannel] to /// communication with native plugin -class Transaction extends TransactionPlatform { - /// [FirebaseApp] name used for this [Transaction] +class MethodChannelTransaction extends TransactionPlatform { + /// [FirebaseApp] name used for this [MethodChannelTransaction] final String appName; + int _transactionId; - // disabling lint as it's only visible for testing - // ignore: public_member_api_docs - @visibleForTesting - Transaction(int transactionId, this.appName) - : super( - transactionId, + /// Constructor. + MethodChannelTransaction(int transactionId, this.appName) + : _transactionId = transactionId, + super( appName == FirebaseApp.defaultAppName ? FirestorePlatform.instance : FirestorePlatform.instanceFor( app: FirebaseApp(name: appName))); @override - Future _get(DocumentReferencePlatform documentReference) async { + Future doGet(DocumentReferencePlatform documentReference) async { final Map result = await MethodChannelFirestore.channel .invokeMapMethod('Transaction#get', { 'app': firestore.app.name, @@ -42,7 +49,7 @@ class Transaction extends TransactionPlatform { } @override - Future _delete(DocumentReferencePlatform documentReference) async { + Future doDelete(DocumentReferencePlatform documentReference) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#delete', { 'app': firestore.app.name, @@ -52,7 +59,7 @@ class Transaction extends TransactionPlatform { } @override - Future _update( + Future doUpdate( DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#update', { @@ -64,7 +71,7 @@ class Transaction extends TransactionPlatform { } @override - Future _set( + Future doSet( DocumentReferencePlatform documentReference, Map data) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#set', { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index 72a36cc7bc45..d1c41175544f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -2,17 +2,21 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'dart:async'; -/// A [WriteBatch] is a series of write operations to be performed as one unit. +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +import 'method_channel_firestore.dart'; + +/// A [MethodChannelWriteBatch] is a series of write operations to be performed as one unit. /// -/// Operations done on a [WriteBatch] do not take effect until you [commit]. +/// Operations done on a [MethodChannelWriteBatch] do not take effect until you [commit]. /// -/// Once committed, no further operations can be performed on the [WriteBatch], +/// Once committed, no further operations can be performed on the [MethodChannelWriteBatch], /// nor can it be committed again. -class WriteBatch extends WriteBatchPlatform { - /// Create an instance of [WriteBatch] - WriteBatch(this._firestore) +class MethodChannelWriteBatch extends WriteBatchPlatform { + /// Create an instance of [MethodChannelWriteBatch] + MethodChannelWriteBatch(this._firestore) : _handle = MethodChannelFirestore.channel.invokeMethod( 'WriteBatch#create', {'app': _firestore.app.name}), @@ -21,6 +25,7 @@ class WriteBatch extends WriteBatchPlatform { final FirestorePlatform _firestore; Future _handle; final List> _actions = >[]; + bool _committed = false; @override Future commit() async { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index 224ce849fc80..0f1522e05029 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -1,8 +1,13 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. 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:convert'; -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:meta/meta.dart' show visibleForTesting; @visibleForTesting // ignoring lint rule here as it's only visible for testing @@ -36,9 +41,9 @@ class FirestoreMessageCodec extends StandardMessageCodec { FieldValueType.incrementInteger: _kIncrementInteger, }; - static const Map<_FieldPathType, int> _kFieldPathCodes = - <_FieldPathType, int>{ - _FieldPathType.documentId: _kDocumentId, + static const Map _kFieldPathCodes = + { + FieldPathType.documentId: _kDocumentId, }; @override diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/maps.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index c3d895acdca9..22c40d722980 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -52,7 +52,8 @@ abstract class QueryPlatform extends PlatformInterface { /// Represents the path referenced by `this` [QueryPlatform] String get path => pathComponents.join('/'); - QueryPlatform _copyWithParameters(Map parameters) { + /// Returns a copy of this query, with additional [parameters]. + QueryPlatform copyWithParameters(Map parameters) { throw UnimplementedError("copyWithParameters() is not implemented"); } @@ -240,6 +241,6 @@ abstract class QueryPlatform extends PlatformInterface { /// to the specified number of documents. QueryPlatform limit(int length) { assert(!parameters.containsKey('limit')); - return _copyWithParameters({'limit': length}); + return copyWithParameters({'limit': length}); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 99a0af7fe927..12b4462b0c1b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -13,7 +13,7 @@ abstract class TransactionPlatform extends PlatformInterface { // disabling lint as it's only visible for testing // ignore: public_member_api_docs @visibleForTesting - TransactionPlatform(this._transactionId, this.firestore) : super(token: _token); + TransactionPlatform(this.firestore) : super(token: _token); static final Object _token = Object(); @@ -27,8 +27,6 @@ abstract class TransactionPlatform extends PlatformInterface { PlatformInterface.verifyToken(instance, _token); } - int _transactionId; - /// [FirestorePlatform] instance used for this [TransactionPlatform] FirestorePlatform firestore; List> _pendingResults = >[]; @@ -38,12 +36,16 @@ abstract class TransactionPlatform extends PlatformInterface { /// Reads the document referenced by the provided DocumentReference. Future get(DocumentReferencePlatform documentReference) { - final Future result = _get(documentReference); + final Future result = doGet(documentReference); _pendingResults.add(result); return result; } - Future _get(DocumentReferencePlatform documentReference) async { + /// Reads the document referenced by the provided DocumentReference. + /// This is here so it can be overridden by implementations that do NOT + /// handle returned futures automatically, like the [MethodChannelTransaction]. + /// Does not affect the _pendingResults. + Future doGet(DocumentReferencePlatform documentReference) async { throw UnimplementedError("get() not implemented"); } @@ -52,12 +54,16 @@ abstract class TransactionPlatform extends PlatformInterface { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future delete(DocumentReferencePlatform documentReference) { - final Future result = _delete(documentReference); + final Future result = doDelete(documentReference); _pendingResults.add(result); return result; } - Future _delete(DocumentReferencePlatform documentReference) async { + /// Deletes the document referred to by the provided [documentReference]. + /// This is here so it can be overridden by implementations that do NOT + /// handle returned futures automatically, like the [MethodChannelTransaction]. + /// Does not affect the _pendingResults. + Future doDelete(DocumentReferencePlatform documentReference) async { throw UnimplementedError("delete() not implemented"); } @@ -68,12 +74,17 @@ abstract class TransactionPlatform extends PlatformInterface { /// when the transaction handler completes. Future update( DocumentReferencePlatform documentReference, Map data) async { - final Future result = _update(documentReference, data); + final Future result = doUpdate(documentReference, data); _pendingResults.add(result); return result; } - Future _update( + /// Updates fields in the document referred to by [documentReference]. + /// The update will fail if applied to a document that does not exist. + /// This is here so it can be overridden by implementations that do NOT + /// handle returned futures automatically, like the [MethodChannelTransaction]. + /// Does not affect the _pendingResults. + Future doUpdate( DocumentReferencePlatform documentReference, Map data) async { throw UnimplementedError("updated() not implemented"); } @@ -86,12 +97,18 @@ abstract class TransactionPlatform extends PlatformInterface { /// when the transaction handler completes. Future set( DocumentReferencePlatform documentReference, Map data) { - final Future result = _set(documentReference, data); + final Future result = doSet(documentReference, data); _pendingResults.add(result); return result; } - Future _set( + /// Writes to the document referred to by the provided [DocumentReferencePlatform]. + /// If the document does not exist yet, it will be created. If you pass + /// SetOptions, the provided data can be merged into the existing document. + /// This is here so it can be overridden by implementations that do NOT + /// handle returned futures automatically, like the [MethodChannelTransaction]. + /// Does not affect the _pendingResults. + Future doSet( DocumentReferencePlatform documentReference, Map data) async { throw UnimplementedError("set() not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index cc9c3b0e6b23..0cf9c6c797dc 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -25,9 +25,6 @@ abstract class WriteBatchPlatform extends PlatformInterface { PlatformInterface.verifyToken(instance, _token); } - /// Indicator to whether or not this [WriteBatch] has been committed. - bool _committed = false; - /// Commits all of the writes in this write batch as a single atomic unit. /// /// Calling this method prevents any future operations from being added. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart index 77364e23a024..88b312f55db9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart @@ -25,7 +25,7 @@ enum Source { } /// Converts [Source] to [String] -String _getSourceString(Source source) { +String getSourceString(Source source) { assert(source != null); if (source == Source.server) { return 'server'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 86eaa727c0fa..d2695f3d70f9 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -1,7 +1,6 @@ // Copyright 2017 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 'dart:typed_data'; @@ -10,6 +9,10 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_transaction.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart'; + void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -20,7 +23,7 @@ void main() { final List log = []; CollectionReferencePlatform collectionReference; QueryPlatform collectionGroupQuery; - Transaction transaction; + TransactionPlatform transaction; const Map kMockDocumentSnapshotData = { '1': 2 }; @@ -47,7 +50,7 @@ void main() { firestore = MethodChannelFirestore(app: app); collectionReference = firestore.collection('foo'); collectionGroupQuery = firestore.collectionGroup('bar'); - transaction = Transaction(0, firestore.app.name); + transaction = MethodChannelTransaction(0, firestore.app.name); MethodChannelFirestore.channel .setMockMethodCallHandler((MethodCall methodCall) async { log.add(methodCall); @@ -1243,7 +1246,7 @@ void main() { group('WriteBatch', () { test('set', () async { - final WriteBatch batch = firestore.batch(); + final WriteBatchPlatform batch = firestore.batch(); batch.setData( collectionReference.document('bar'), {'bazKey': 'quxValue'}, @@ -1275,7 +1278,7 @@ void main() { ); }); test('merge set', () async { - final WriteBatch batch = firestore.batch(); + final WriteBatchPlatform batch = firestore.batch(); batch.setData( collectionReference.document('bar'), {'bazKey': 'quxValue'}, @@ -1305,7 +1308,7 @@ void main() { ); }); test('update', () async { - final WriteBatch batch = firestore.batch(); + final WriteBatchPlatform batch = firestore.batch(); batch.updateData( collectionReference.document('bar'), {'bazKey': 'quxValue'}, @@ -1339,7 +1342,7 @@ void main() { ); }); test('delete', () async { - final WriteBatch batch = firestore.batch(); + final WriteBatchPlatform batch = firestore.batch(); batch.delete(collectionReference.document('bar')); await batch.commit(); expect( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart index ee650b499a11..0083f8db1ce7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart @@ -2,6 +2,9 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_collection_reference.dart'; + const _kCollectionId = "test"; const _kDocumentId = "document"; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 6779f4d34f86..36e677ba2e0d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -2,6 +2,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart'; + import 'test_common.dart'; class MockFiledValue extends Mock implements FieldValuePlatform {} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart index f67d384e2eec..201c993a808a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart @@ -1,6 +1,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; + void main() { group("$MethodChannelFieldValueFactory()", () { final MethodChannelFieldValueFactory factory = diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart index 7bf80c06b11f..d90c224f6130 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart @@ -1,6 +1,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_query.dart'; + const _kQueryPath = "test/collection"; class TestQuery extends MethodChannelQuery { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index 2fa304987917..3998edf98dde 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -2,6 +2,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; + typedef MethodCallCallback = dynamic Function(MethodCall methodCall); const kCollectionId = "test"; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 539ad8d586a9..75689549d2ce 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -2,6 +2,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_transaction.dart'; + import 'test_common.dart'; class MockDocumentReference extends Mock implements DocumentReferencePlatform {} @@ -14,13 +16,13 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); final mockFieldValue = MockFiledValue(); - group("$Transaction()", () { - Transaction transaction; + group("$MethodChannelTransaction()", () { + TransactionPlatform transaction; final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); setUp(() { transaction = - Transaction(_kTransactionId, FirestorePlatform.instance.app.name); + MethodChannelTransaction(_kTransactionId, FirestorePlatform.instance.app.name); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 87566543d9f2..7db8940beb4a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -1,6 +1,5 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -import 'package:meta/meta.dart'; import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; @@ -12,10 +11,8 @@ class TransactionWeb extends TransactionPlatform { @override FirestorePlatform firestore; - static int _transactionId = 0; - /// Constructor. - TransactionWeb(this._webTransaction, this.firestore) : super(_transactionId++, firestore); + TransactionWeb(this._webTransaction, this.firestore) : super(firestore); @override Future delete(DocumentReferencePlatform documentReference) async { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart index e6ed15ecff94..4c6a4aafc2b1 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -1,12 +1,11 @@ @TestOn("chrome") -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/src/write_batch_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'test_common.dart'; void main() { - group("$WriteBatch()", () { + group("$WriteBatchWeb()", () { final mockWebTransaction = MockWebWriteBatch(); final mockWebDocumentReference = MockWebDocumentReference(); final mockDocumentReference = MockDocumentReference(); From 15dd903cbbef6f0c729eb6ebd6616885473e6ff4 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 13:19:57 -0800 Subject: [PATCH 122/144] analyze + dartfmt --- .../cloud_firestore/lib/cloud_firestore.dart | 1 - .../cloud_firestore/lib/src/field_value.dart | 16 +-- .../method_channel_field_value_factory.dart | 3 +- .../method_channel_firestore.dart | 28 +++-- .../method_channel/method_channel_query.dart | 31 +++-- .../method_channel_query_snapshot.dart | 4 +- .../method_channel_transaction.dart | 24 ++-- .../method_channel_write_batch.dart | 15 ++- .../utils/firestore_message_codec.dart | 13 +-- .../collection_reference.dart | 6 +- .../platform_interface/document_change.dart | 7 +- .../document_reference.dart | 18 ++- .../src/platform_interface/field_value.dart | 6 +- .../lib/src/platform_interface/query.dart | 28 +++-- .../platform_interface/query_snapshot.dart | 6 +- .../src/platform_interface/transaction.dart | 20 +++- .../src/platform_interface/write_batch.dart | 12 +- .../method_channel_cloud_firestore_test.dart | 15 ++- .../method_channel_document_reference.dart | 4 +- .../test/transaction_test.dart | 4 +- .../lib/src/collection_reference_web.dart | 42 ++++--- .../lib/src/document_reference_web.dart | 25 +++-- .../lib/src/query_web.dart | 106 +++++++++++------- .../lib/src/transaction_web.dart | 12 +- .../lib/src/utils/codec_utility.dart | 25 ++--- .../lib/src/write_batch_web.dart | 13 ++- 26 files changed, 301 insertions(+), 183 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 72180140f61e..19f8edcbdca3 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -11,7 +11,6 @@ import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/services.dart'; import 'package:meta/meta.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 20a99c9558d8..58bfaceadc50 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -29,8 +29,8 @@ class FieldValue implements platform.FieldValuePlatform { /// added to the end. If the field being modified is not already an array it /// will be overwritten with an array containing exactly the specified /// elements. - static FieldValue arrayUnion(List elements) => - FieldValue._(platform.FieldValueFactoryPlatform.instance.arrayUnion(elements)); + static FieldValue arrayUnion(List elements) => FieldValue._( + platform.FieldValueFactoryPlatform.instance.arrayUnion(elements)); /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -38,8 +38,8 @@ class FieldValue implements platform.FieldValuePlatform { /// All instances of each element specified will be removed from the array. /// If the field being modified is not already an array it will be overwritten /// with an empty array. - static FieldValue arrayRemove(List elements) => - FieldValue._(platform.FieldValueFactoryPlatform.instance.arrayRemove(elements)); + static FieldValue arrayRemove(List elements) => FieldValue._( + platform.FieldValueFactoryPlatform.instance.arrayRemove(elements)); /// Returns a sentinel for use with update() to mark a field for deletion. static FieldValue delete() => @@ -47,11 +47,11 @@ class FieldValue implements platform.FieldValuePlatform { /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. - static FieldValue serverTimestamp() => - FieldValue._(platform.FieldValueFactoryPlatform.instance.serverTimestamp()); + static FieldValue serverTimestamp() => FieldValue._( + platform.FieldValueFactoryPlatform.instance.serverTimestamp()); /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - static FieldValue increment(num value) => - FieldValue._(platform.FieldValueFactoryPlatform.instance.increment(value)); + static FieldValue increment(num value) => FieldValue._( + platform.FieldValueFactoryPlatform.instance.increment(value)); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 04634cc5a69e..001bf496b819 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -14,7 +14,8 @@ class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { FieldValuePlatform(FieldValueType.arrayUnion, elements); @override - FieldValuePlatform delete() => FieldValuePlatform(FieldValueType.delete, null); + FieldValuePlatform delete() => + FieldValuePlatform(FieldValueType.delete, null); @override FieldValuePlatform increment(num value) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index 7fda9d6e1993..e46947b6709a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -63,9 +63,15 @@ class MethodChannelFirestore extends FirestorePlatform { StandardMethodCodec(FirestoreMessageCodec()), ); - static final Map> queryObservers = - >{}; - + /// A map containing all the pending Query Observers, keyed by their id. + /// This is shared amongst all [MethodChannelQuery] objects, and the `QuerySnapshot` + /// `MethodCall` handler initialized in the constructor of this class. + static final Map> + queryObservers = >{}; + + /// A map containing all the pending Document Observers, keyed by their id. + /// This is shared amongst all [MethodChannelDocumentReference] objects, and the + /// `DocumentSnapshot` `MethodCall` handler initialized in the constructor of this class. static final Map> documentObservers = >{}; @@ -105,8 +111,9 @@ class MethodChannelFirestore extends FirestorePlatform { @override Future> runTransaction( - TransactionHandler transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) async { + TransactionHandler transactionHandler, { + Duration timeout = const Duration(seconds: 5), + }) async { assert(timeout.inMilliseconds > 0, 'Transaction timeout must be more than 0 milliseconds'); final int transactionId = _transactionHandlerId++; @@ -132,11 +139,12 @@ class MethodChannelFirestore extends FirestorePlatform { } @override - Future settings( - {bool persistenceEnabled, - String host, - bool sslEnabled, - int cacheSizeBytes}) async { + Future settings({ + bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes, + }) async { await channel.invokeMethod('Firestore#settings', { 'app': app.name, 'persistenceEnabled': persistenceEnabled, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index 2a2e80142026..c59582b42da5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -41,7 +41,9 @@ class MethodChannelQuery extends QueryPlatform { // TODO(jackson): Reduce code duplication with [DocumentReference] @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({ + bool includeMetadataChanges = false, + }) { assert(includeMetadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the @@ -101,16 +103,18 @@ class MethodChannelQuery extends QueryPlatform { }); @override - QueryPlatform where(field, - {isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull}) { + QueryPlatform where( + field, { + isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); @@ -156,7 +160,10 @@ class MethodChannelQuery extends QueryPlatform { } @override - QueryPlatform orderBy(field, {bool descending = false}) { + QueryPlatform orderBy( + field, { + bool descending = false, + }) { assert(field != null && descending != null); assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index f59c06e1293a..de6b3c75963a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -24,8 +24,8 @@ class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { firestore, ); }), - List.generate(data['documentChanges'].length, - (int index) { + List.generate( + data['documentChanges'].length, (int index) { return MethodChannelDocumentChange( data['documentChanges'][index], firestore, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index 3b283518a631..abb6a86975af 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -5,9 +5,7 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:meta/meta.dart' show visibleForTesting; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'method_channel_firestore.dart'; @@ -21,15 +19,15 @@ class MethodChannelTransaction extends TransactionPlatform { /// Constructor. MethodChannelTransaction(int transactionId, this.appName) - : _transactionId = transactionId, - super( - appName == FirebaseApp.defaultAppName - ? FirestorePlatform.instance - : FirestorePlatform.instanceFor( - app: FirebaseApp(name: appName))); + : _transactionId = transactionId, + super(appName == FirebaseApp.defaultAppName + ? FirestorePlatform.instance + : FirestorePlatform.instanceFor(app: FirebaseApp(name: appName))); @override - Future doGet(DocumentReferencePlatform documentReference) async { + Future doGet( + DocumentReferencePlatform documentReference, + ) async { final Map result = await MethodChannelFirestore.channel .invokeMapMethod('Transaction#get', { 'app': firestore.app.name, @@ -60,7 +58,9 @@ class MethodChannelTransaction extends TransactionPlatform { @override Future doUpdate( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#update', { 'app': firestore.app.name, @@ -72,7 +72,9 @@ class MethodChannelTransaction extends TransactionPlatform { @override Future doSet( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { return MethodChannelFirestore.channel .invokeMethod('Transaction#set', { 'app': firestore.app.name, diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index d1c41175544f..5bd5ae60298c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -18,8 +18,7 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { /// Create an instance of [MethodChannelWriteBatch] MethodChannelWriteBatch(this._firestore) : _handle = MethodChannelFirestore.channel.invokeMethod( - 'WriteBatch#create', - {'app': _firestore.app.name}), + 'WriteBatch#create', {'app': _firestore.app.name}), super(); final FirestorePlatform _firestore; @@ -56,8 +55,11 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { } @override - void setData(DocumentReferencePlatform document, Map data, - {bool merge = false}) { + void setData( + DocumentReferencePlatform document, + Map data, { + bool merge = false, + }) { _assertNotCommitted(); _handle.then((dynamic handle) { @@ -77,7 +79,10 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { } @override - void updateData(DocumentReferencePlatform document, Map data) { + void updateData( + DocumentReferencePlatform document, + Map data, + ) { _assertNotCommitted(); _handle.then((dynamic handle) { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index 0f1522e05029..bfe1410d4ee1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -7,15 +7,11 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -import 'package:meta/meta.dart' show visibleForTesting; -@visibleForTesting -// ignoring lint rule here as it's only visible for testing -// ignore: public_member_api_docs +/// The codec utilized to encode data back and forth between +/// the Dart application and the native platform. class FirestoreMessageCodec extends StandardMessageCodec { - // ignoring lint rule here as it's only visible for testing - // ignore: public_member_api_docs - @visibleForTesting + /// Constructor. const FirestoreMessageCodec(); static const int _kDateTime = 128; @@ -41,8 +37,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { FieldValueType.incrementInteger: _kIncrementInteger, }; - static const Map _kFieldPathCodes = - { + static const Map _kFieldPathCodes = { FieldPathType.documentId: _kDocumentId, }; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index 179dbedc90f2..1bce1e165ff3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -10,8 +10,10 @@ part of cloud_firestore_platform_interface; /// Note: QueryPlatform extends PlatformInterface already. abstract class CollectionReferencePlatform extends QueryPlatform { /// Create a [CollectionReferencePlatform] using [pathComponents] - CollectionReferencePlatform(FirestorePlatform firestore, List pathComponents) - : super(firestore: firestore, pathComponents: pathComponents); + CollectionReferencePlatform( + FirestorePlatform firestore, + List pathComponents, + ) : super(firestore: firestore, pathComponents: pathComponents); /// Identifier of the referenced collection. String get id => pathComponents.isEmpty ? null : pathComponents.last; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 53c3bc24989f..56d0699de1ab 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -24,7 +24,12 @@ enum DocumentChangeType { /// (added, modified, or removed). class DocumentChangePlatform extends PlatformInterface { /// Create a [DocumentChangePlatform] - DocumentChangePlatform(this.type, this.oldIndex, this.newIndex, this.document) : super(token: _token); + DocumentChangePlatform( + this.type, + this.oldIndex, + this.newIndex, + this.document, + ) : super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 814adf3637f8..67bc61600ece 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -8,7 +8,10 @@ part of cloud_firestore_platform_interface; /// [CollectionReferencePlatform] to a subcollection. abstract class DocumentReferencePlatform extends PlatformInterface { /// Create instance of [DocumentReferencePlatform] - DocumentReferencePlatform(this.firestore, this._pathComponents) : super(token: _token); + DocumentReferencePlatform( + this.firestore, + this._pathComponents, + ) : super(token: _token); static final Object _token = Object(); @@ -28,7 +31,9 @@ abstract class DocumentReferencePlatform extends PlatformInterface { @override bool operator ==(dynamic o) => - o is DocumentReferencePlatform && o.firestore == firestore && o.path == path; + o is DocumentReferencePlatform && + o.firestore == firestore && + o.path == path; @override int get hashCode => hashList(_pathComponents); @@ -54,7 +59,10 @@ abstract class DocumentReferencePlatform extends PlatformInterface { /// /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. - Future setData(Map data, {bool merge = false}) { + Future setData( + Map data, { + bool merge = false, + }) { throw UnimplementedError("setData() is not implemented"); } @@ -71,7 +79,9 @@ abstract class DocumentReferencePlatform extends PlatformInterface { /// Reads the document referenced by this [DocumentReferencePlatform]. /// /// If no document exists, the read will return null. - Future get({Source source = Source.serverAndCache}) async { + Future get({ + Source source = Source.serverAndCache, + }) async { throw UnimplementedError("get() is not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index c1226a5cb00f..4eee4cc96df8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -18,7 +18,8 @@ abstract class FieldValueInterface { } /// Platform Interface of a FieldValue; implementation for [FieldValueInterface] -class FieldValuePlatform extends PlatformInterface implements FieldValueInterface { +class FieldValuePlatform extends PlatformInterface + implements FieldValueInterface { /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValuePlatform] static Map serverDelegates(Map data) { @@ -27,7 +28,8 @@ class FieldValuePlatform extends PlatformInterface implements FieldValueInterfac } Map output = Map.from(data); output.updateAll((key, value) { - if (value is FieldValueInterface && value.instance is FieldValuePlatform) { + if (value is FieldValueInterface && + value.instance is FieldValuePlatform) { return value.instance; } else { return value; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index 22c40d722980..eaac7c1a728f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -7,12 +7,12 @@ part of cloud_firestore_platform_interface; /// Represents a query over the data at a particular location. abstract class QueryPlatform extends PlatformInterface { /// Create a [QueryPlatform] instance - QueryPlatform( - {@required this.firestore, - @required List pathComponents, - bool isCollectionGroup = false, - Map parameters}) - : pathComponents = pathComponents, + QueryPlatform({ + @required this.firestore, + @required List pathComponents, + bool isCollectionGroup = false, + Map parameters, + }) : pathComponents = pathComponents, isCollectionGroup = isCollectionGroup, parameters = parameters ?? Map.unmodifiable({ @@ -20,7 +20,7 @@ abstract class QueryPlatform extends PlatformInterface { 'orderBy': List>.unmodifiable(>[]), }), assert(firestore != null), - assert(pathComponents != null), + assert(pathComponents != null), super(token: _token); static final Object _token = Object(); @@ -63,13 +63,16 @@ abstract class QueryPlatform extends PlatformInterface { } /// Notifies of query results at this location - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({ + bool includeMetadataChanges = false, + }) { throw UnimplementedError("snapshots() is not implemented"); } /// Fetch the documents for this query - Future getDocuments( - {Source source = Source.serverAndCache}) async { + Future getDocuments({ + Source source = Source.serverAndCache, + }) async { throw UnimplementedError("getDocuments() is not implemented"); } @@ -113,7 +116,10 @@ abstract class QueryPlatform extends PlatformInterface { /// using [startAfterDocument], [startAtDocument], [endAfterDocument], /// or [endAtDocument] because the order by clause on the document id /// is added by these methods implicitly. - QueryPlatform orderBy(dynamic field, {bool descending = false}) { + QueryPlatform orderBy( + dynamic field, { + bool descending = false, + }) { throw UnimplementedError("orderBy() is not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index ccfc000acb71..7b88dae1ac2f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -7,7 +7,11 @@ part of cloud_firestore_platform_interface; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshotPlatform extends PlatformInterface { /// Create a [QuerySnapshotPlatform] - QuerySnapshotPlatform(this.documents, this.documentChanges, this.metadata) : super(token: _token); + QuerySnapshotPlatform( + this.documents, + this.documentChanges, + this.metadata, + ) : super(token: _token); static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 12b4462b0c1b..53fc445e3322 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -45,7 +45,9 @@ abstract class TransactionPlatform extends PlatformInterface { /// This is here so it can be overridden by implementations that do NOT /// handle returned futures automatically, like the [MethodChannelTransaction]. /// Does not affect the _pendingResults. - Future doGet(DocumentReferencePlatform documentReference) async { + Future doGet( + DocumentReferencePlatform documentReference, + ) async { throw UnimplementedError("get() not implemented"); } @@ -73,7 +75,9 @@ abstract class TransactionPlatform extends PlatformInterface { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future update( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { final Future result = doUpdate(documentReference, data); _pendingResults.add(result); return result; @@ -85,7 +89,9 @@ abstract class TransactionPlatform extends PlatformInterface { /// handle returned futures automatically, like the [MethodChannelTransaction]. /// Does not affect the _pendingResults. Future doUpdate( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { throw UnimplementedError("updated() not implemented"); } @@ -96,7 +102,9 @@ abstract class TransactionPlatform extends PlatformInterface { /// Awaiting the returned [Future] is optional and will be done automatically /// when the transaction handler completes. Future set( - DocumentReferencePlatform documentReference, Map data) { + DocumentReferencePlatform documentReference, + Map data, + ) { final Future result = doSet(documentReference, data); _pendingResults.add(result); return result; @@ -109,7 +117,9 @@ abstract class TransactionPlatform extends PlatformInterface { /// handle returned futures automatically, like the [MethodChannelTransaction]. /// Does not affect the _pendingResults. Future doSet( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { throw UnimplementedError("set() not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index 0cf9c6c797dc..10056cb52f69 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -43,15 +43,21 @@ abstract class WriteBatchPlatform extends PlatformInterface { /// /// If [merge] is true, the provided data will be merged into an /// existing document instead of overwriting. - void setData(DocumentReferencePlatform document, Map data, - {bool merge = false}) { + void setData( + DocumentReferencePlatform document, + Map data, { + bool merge = false, + }) { throw UnimplementedError("commit() not implemented"); } /// Updates fields in the document referred to by [document]. /// /// If the document does not exist, the operation will fail. - void updateData(DocumentReferencePlatform document, Map data) { + void updateData( + DocumentReferencePlatform document, + Map data, + ) { throw UnimplementedError("commit() not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index d2695f3d70f9..7fc4938d3968 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -332,7 +332,8 @@ void main() { expect(collectionReference.id, equals('foo')); }); test('parent', () async { - final DocumentReferencePlatform docRef = collectionReference.document('bar'); + final DocumentReferencePlatform docRef = + collectionReference.document('bar'); expect(docRef.parent().id, equals('foo')); expect(collectionReference.parent(), isNull); }); @@ -879,7 +880,8 @@ void main() { ); }); test('getDocumentsFromCollectionGroup', () async { - QuerySnapshotPlatform snapshot = await collectionGroupQuery.getDocuments(); + QuerySnapshotPlatform snapshot = + await collectionGroupQuery.getDocuments(); expect(snapshot.metadata.hasPendingWrites, equals(kMockSnapshotMetadata['hasPendingWrites'])); expect(snapshot.metadata.isFromCache, @@ -1158,7 +1160,8 @@ void main() { codec, FieldValueFactoryPlatform.instance.arrayUnion([123])); _checkEncodeDecode( codec, FieldValueFactoryPlatform.instance.arrayRemove([123])); - _checkEncodeDecode(codec, FieldValueFactoryPlatform.instance.delete()); + _checkEncodeDecode( + codec, FieldValueFactoryPlatform.instance.delete()); _checkEncodeDecode( codec, FieldValueFactoryPlatform.instance.serverTimestamp()); _checkEncodeDecode( @@ -1399,7 +1402,8 @@ bool _deepEquals(dynamic valueA, dynamic valueB) { if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; if (valueA is FieldValuePlatform) { - return valueB is FieldValuePlatform && _deepEqualsFieldValue(valueA, valueB); + return valueB is FieldValuePlatform && + _deepEqualsFieldValue(valueA, valueB); } if (valueA is FieldPath) { return valueB is FieldPath && valueA.type == valueB.type; @@ -1447,7 +1451,8 @@ bool _deepEqualsMap( return true; } -bool _deepEqualsFieldValue(FieldValuePlatform valueA, FieldValuePlatform valueB) { +bool _deepEqualsFieldValue( + FieldValuePlatform valueA, FieldValuePlatform valueB) { if (valueA.type != valueB.type) return false; if (valueA.value == null) return valueB.value == null; if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 36e677ba2e0d..da50d20a5b85 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -83,8 +83,8 @@ void main() { }); } -void _assertGetMethodCalled(DocumentReferencePlatform documentReference, Source source, - String expectedSourceString) async { +void _assertGetMethodCalled(DocumentReferencePlatform documentReference, + Source source, String expectedSourceString) async { bool isMethodCalled = false; handleMethodCall((call) { if (call.method == "DocumentReference#get") { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 75689549d2ce..ab57fad4bbfc 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -21,8 +21,8 @@ void main() { final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); setUp(() { - transaction = - MethodChannelTransaction(_kTransactionId, FirestorePlatform.instance.app.name); + transaction = MethodChannelTransaction( + _kTransactionId, FirestorePlatform.instance.app.name); reset(mockFieldValue); when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); when(mockFieldValue.value).thenReturn(2.0); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index a68da59dbc05..ede6440b89e0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -19,8 +19,11 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { /// at [pathComponents] and uses implementation of [webFirestore] CollectionReferenceWeb( this._firestorePlatform, this.webFirestore, this.pathComponents) - : queryDelegate = QueryWeb(_firestorePlatform, pathComponents.join("/"), - webFirestore.collection(pathComponents.join("/")),), + : queryDelegate = QueryWeb( + _firestorePlatform, + pathComponents.join("/"), + webFirestore.collection(pathComponents.join("/")), + ), super(_firestorePlatform, pathComponents); @override @@ -89,7 +92,9 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { FirestorePlatform get firestore => _firestorePlatform; @override - Future getDocuments({Source source = Source.serverAndCache}) => + Future getDocuments({ + Source source = Source.serverAndCache, + }) => queryDelegate.getDocuments(source: source); @override @@ -105,7 +110,10 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform orderBy(field, {bool descending = false}) { + QueryPlatform orderBy( + field, { + bool descending = false, + }) { _resetQueryDelegate(); return queryDelegate.orderBy(field, descending: descending); } @@ -120,7 +128,9 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { CollectionReferencePlatform reference() => queryDelegate.reference(); @override - Stream snapshots({bool includeMetadataChanges = false}) => + Stream snapshots({ + bool includeMetadataChanges = false, + }) => queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); @override @@ -148,16 +158,18 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform where(field, - {isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull}) { + QueryPlatform where( + field, { + isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { _resetQueryDelegate(); return queryDelegate.where(field, isEqualTo: isEqualTo, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart index 8ac651273bf9..1d7ad626292e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -15,22 +15,31 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { /// Creates an instance of [CollectionReferenceWeb] which represents path /// at [pathComponents] and uses implementation of [firestoreWeb] - DocumentReferenceWeb(this.firestoreWeb, FirestorePlatform firestore, - List pathComponents) - : delegate = firestoreWeb.doc(pathComponents.join("/")), + DocumentReferenceWeb( + this.firestoreWeb, + FirestorePlatform firestore, + List pathComponents, + ) : delegate = firestoreWeb.doc(pathComponents.join("/")), super(firestore, pathComponents); @override - Future setData(Map data, {bool merge = false}) => + Future setData( + Map data, { + bool merge = false, + }) => delegate.set( - CodecUtility.encodeMapData(data), web.SetOptions(merge: merge)); + CodecUtility.encodeMapData(data), + web.SetOptions(merge: merge), + ); @override Future updateData(Map data) => delegate.update(data: CodecUtility.encodeMapData(data)); @override - Future get({Source source = Source.serverAndCache}) async { + Future get({ + Source source = Source.serverAndCache, + }) async { return fromWebDocumentSnapshotToPlatformDocumentSnapshot( await delegate.get(), this.firestore); } @@ -39,7 +48,9 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { Future delete() => delegate.delete(); @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({ + bool includeMetadataChanges = false, + }) { Stream querySnapshots = delegate.onSnapshot; if (includeMetadataChanges) { querySnapshots = delegate.onMetadataChangesSnapshot; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index 15d1ab075fe5..a31618028b4f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -1,6 +1,5 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -import 'package:meta/meta.dart'; import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; @@ -17,14 +16,24 @@ class QueryWeb extends QueryPlatform { /// Builds an instance of [QueryWeb] using [_path] & [_webQuery] /// to delegate queries to underlying firestore web plugin - QueryWeb(this._firestore, this._path, this._webQuery, - {bool isCollectionGroup, List orderByKeys}) - : this._isCollectionGroup = isCollectionGroup ?? false, + QueryWeb( + this._firestore, + this._path, + this._webQuery, { + bool isCollectionGroup, + List orderByKeys, + }) : this._isCollectionGroup = isCollectionGroup ?? false, this._orderByKeys = orderByKeys ?? [], - super(firestore: _firestore, pathComponents: _path.split('/'), isCollectionGroup: isCollectionGroup,); + super( + firestore: _firestore, + pathComponents: _path.split('/'), + isCollectionGroup: isCollectionGroup, + ); @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots({ + bool includeMetadataChanges = false, + }) { assert(_webQuery != null); Stream querySnapshots = _webQuery.onSnapshot; if (includeMetadataChanges) { @@ -34,8 +43,9 @@ class QueryWeb extends QueryPlatform { } @override - Future getDocuments( - {Source source = Source.serverAndCache}) async { + Future getDocuments({ + Source source = Source.serverAndCache, + }) async { assert(_webQuery != null); return _webQuerySnapshotToQuerySnapshot(await _webQuery.get()); } @@ -44,9 +54,12 @@ class QueryWeb extends QueryPlatform { Map buildArguments() => Map(); @override - QueryPlatform endAt(List values) => QueryWeb(this._firestore, this._path, - _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, - isCollectionGroup: _isCollectionGroup); + QueryPlatform endAt(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup, + ); @override QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { @@ -61,9 +74,12 @@ class QueryWeb extends QueryPlatform { } @override - QueryPlatform endBefore(List values) => QueryWeb(this._firestore, this._path, - _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, - isCollectionGroup: _isCollectionGroup); + QueryPlatform endBefore(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup, + ); @override QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { @@ -93,7 +109,10 @@ class QueryWeb extends QueryPlatform { ); @override - QueryPlatform orderBy(field, {bool descending = false}) { + QueryPlatform orderBy( + field, { + bool descending = false, + }) { dynamic usableField = field; if (field == FieldPath.documentId) { usableField = web.FieldPath.documentId(); @@ -118,8 +137,12 @@ class QueryWeb extends QueryPlatform { @override QueryPlatform startAfter(List values) => QueryWeb( - this._firestore, this._path, _webQuery.startAfter(fieldValues: values), - orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); + this._firestore, + this._path, + _webQuery.startAfter(fieldValues: values), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); @override QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { @@ -147,26 +170,30 @@ class QueryWeb extends QueryPlatform { QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( - this._firestore, - this._path, - _webQuery.startAt( - fieldValues: - _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup); + this._firestore, + this._path, + _webQuery.startAt( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList(), + ), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); } @override - QueryPlatform where(field, - {isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull}) { + QueryPlatform where( + field, { + isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); assert(_webQuery != null); @@ -216,7 +243,8 @@ class QueryWeb extends QueryPlatform { } QuerySnapshotPlatform _webQuerySnapshotToQuerySnapshot( - web.QuerySnapshot webSnapshot) { + web.QuerySnapshot webSnapshot, + ) { return QuerySnapshotPlatform( webSnapshot.docs .map((webSnapshot) => @@ -251,15 +279,15 @@ class QueryWeb extends QueryPlatform { SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { return SnapshotMetadata( - webMetadata.hasPendingWrites, webMetadata.fromCache); + webMetadata.hasPendingWrites, + webMetadata.fromCache, + ); } @override Map get parameters => Map(); - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Returns a clean clone of this QueryWeb. QueryWeb resetQueryDelegate() => QueryWeb(firestore, pathComponents.join("/"), _webQuery); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 7db8940beb4a..28687cc744c9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -22,7 +22,9 @@ class TransactionWeb extends TransactionPlatform { } @override - Future get(DocumentReferencePlatform documentReference) async { + Future get( + DocumentReferencePlatform documentReference, + ) async { assert(documentReference is DocumentReferenceWeb); final webSnapshot = await _webTransaction .get((documentReference as DocumentReferenceWeb).delegate); @@ -32,7 +34,9 @@ class TransactionWeb extends TransactionPlatform { @override Future set( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.set( (documentReference as DocumentReferenceWeb).delegate, @@ -41,7 +45,9 @@ class TransactionWeb extends TransactionPlatform { @override Future update( - DocumentReferencePlatform documentReference, Map data) async { + DocumentReferencePlatform documentReference, + Map data, + ) async { assert(documentReference is DocumentReferenceWeb); await _webTransaction.update( (documentReference as DocumentReferenceWeb).delegate, diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index f05703b20f1c..e81859b18962 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -1,14 +1,13 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -import 'package:meta/meta.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; import 'package:cloud_firestore_web/src/document_reference_web.dart'; import 'package:cloud_firestore_web/src/field_value_web.dart'; -// ignore: public_member_api_docs +/// Class containing static utility methods to encode/decode firestore data. class CodecUtility { - // ignore: public_member_api_docs + /// Encodes a Map of values from their proper types to a serialized version. static Map encodeMapData(Map data) { if (data == null) { return null; @@ -18,9 +17,7 @@ class CodecUtility { return output; } - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Encodes an Array of values from their proper types to a serialized version. static List encodeArrayData(List data) { if (data == null) { return null; @@ -28,9 +25,7 @@ class CodecUtility { return List.from(data).map(valueEncode).toList(); } - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Encodes a value from its proper type to a serialized version. static dynamic valueEncode(dynamic value) { if (value is FieldValuePlatform && value.instance is FieldValueWeb) { return (value.instance as FieldValueWeb).delegate; @@ -50,9 +45,7 @@ class CodecUtility { return value; } - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Decodes the values on an incoming Map to their proper types. static Map decodeMapData(Map data) { if (data == null) { return null; @@ -62,9 +55,7 @@ class CodecUtility { return output; } - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Decodes the values on an incoming Array to their proper types. static List decodeArrayData(List data) { if (data == null) { return null; @@ -72,9 +63,7 @@ class CodecUtility { return List.from(data).map(valueDecode).toList(); } - // disabling lint as it's only visible for testing - @visibleForTesting - // ignore: public_member_api_docs + /// Decodes an incoming value to its proper type. static dynamic valueDecode(dynamic value) { if (value is web.GeoPoint) { return GeoPoint(value.latitude, value.longitude); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart index 2ad55f9c37d5..b13fbe480afa 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart @@ -1,6 +1,5 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -import 'package:meta/meta.dart'; import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; import 'package:cloud_firestore_web/src/document_reference_web.dart'; @@ -24,8 +23,11 @@ class WriteBatchWeb extends WriteBatchPlatform { } @override - void setData(DocumentReferencePlatform document, Map data, - {bool merge = false}) { + void setData( + DocumentReferencePlatform document, + Map data, { + bool merge = false, + }) { assert(document is DocumentReferenceWeb); _delegate.set( (document as DocumentReferenceWeb).delegate, @@ -34,7 +36,10 @@ class WriteBatchWeb extends WriteBatchPlatform { } @override - void updateData(DocumentReferencePlatform document, Map data) { + void updateData( + DocumentReferencePlatform document, + Map data, + ) { assert(document is DocumentReferenceWeb); _delegate.update((document as DocumentReferenceWeb).delegate, data: CodecUtility.encodeMapData(data)); From e8fe1a626b0600be2da930ef811ff1699f5c83ce Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 15:23:17 -0800 Subject: [PATCH 123/144] Hide FieldPathType from the world, since it's only used by MethodChannel implementations. --- .../lib/cloud_firestore_platform_interface.dart | 1 + .../lib/src/field_path.dart | 6 ------ .../lib/src/internal/field_path_type.dart | 9 +++++++++ .../method_channel/utils/firestore_message_codec.dart | 2 ++ 4 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/field_path_type.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index f4a4da5cba55..4f5e1b32e9c7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -10,6 +10,7 @@ import 'package:flutter/foundation.dart'; import 'package:meta/meta.dart' show required, visibleForTesting; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'src/internal/field_path_type.dart'; import 'src/method_channel/method_channel_firestore.dart'; import 'src/method_channel/method_channel_field_value_factory.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index 1d6068159027..0ce8b0b0def2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -4,12 +4,6 @@ part of cloud_firestore_platform_interface; -/// The types of field paths supported. -enum FieldPathType { - /// Document ID. - documentId, -} - /// A [FieldPath] refers to a field in a document. class FieldPath { const FieldPath._(this.type); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/field_path_type.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/field_path_type.dart new file mode 100644 index 000000000000..d4bc21cde62c --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/internal/field_path_type.dart @@ -0,0 +1,9 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +/// The types of field paths supported. +enum FieldPathType { + /// Document ID. + documentId, +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index bfe1410d4ee1..a7e14e6e4b8a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -8,6 +8,8 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:cloud_firestore_platform_interface/src/internal/field_path_type.dart'; + /// The codec utilized to encode data back and forth between /// the Dart application and the native platform. class FirestoreMessageCodec extends StandardMessageCodec { From 2b4cde270531b7161752366a71c809304d14bc72 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 15:44:31 -0800 Subject: [PATCH 124/144] Use import/export instead of part in cloud_firestore_platform_interface library. --- .../cloud_firestore_platform_interface.dart | 49 +++++++++---------- .../lib/src/blob.dart | 5 +- .../lib/src/document_snapshot.dart | 3 +- .../lib/src/field_path.dart | 3 +- .../lib/src/geo_point.dart | 3 +- .../collection_reference.dart | 3 +- .../platform_interface/document_change.dart | 3 +- .../document_reference.dart | 7 ++- .../src/platform_interface/field_value.dart | 4 +- .../field_value_factory.dart | 5 +- .../lib/src/platform_interface/query.dart | 8 ++- .../platform_interface/query_snapshot.dart | 4 +- .../src/platform_interface/transaction.dart | 8 ++- .../src/platform_interface/write_batch.dart | 5 +- .../lib/src/snapshot_metadata.dart | 2 - .../lib/src/source.dart | 2 - .../lib/src/timestamp.dart | 3 +- 17 files changed, 70 insertions(+), 47 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 4f5e1b32e9c7..57ef0d0c6a9d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -1,40 +1,39 @@ library cloud_firestore_platform_interface; import 'dart:async'; -import 'dart:typed_data'; -import 'dart:ui'; -import 'package:collection/collection.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart'; -import 'package:meta/meta.dart' show required, visibleForTesting; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -import 'src/internal/field_path_type.dart'; import 'src/method_channel/method_channel_firestore.dart'; -import 'src/method_channel/method_channel_field_value_factory.dart'; -export 'src/utils/auto_id_generator.dart'; +import 'src/platform_interface/collection_reference.dart'; +import 'src/platform_interface/document_reference.dart'; +import 'src/platform_interface/query.dart'; +import 'src/platform_interface/transaction.dart'; +import 'src/platform_interface/write_batch.dart'; -// Platform interface parts -part 'src/platform_interface/field_value_factory.dart'; -part 'src/platform_interface/collection_reference.dart'; -part 'src/platform_interface/document_change.dart'; -part 'src/platform_interface/document_reference.dart'; -part 'src/platform_interface/transaction.dart'; -part 'src/platform_interface/write_batch.dart'; +export 'src/utils/auto_id_generator.dart'; // Shared types -part 'src/blob.dart'; -part 'src/document_snapshot.dart'; -part 'src/field_path.dart'; -part 'src/platform_interface/field_value.dart'; -part 'src/geo_point.dart'; -part 'src/platform_interface/query.dart'; -part 'src/platform_interface/query_snapshot.dart'; -part 'src/snapshot_metadata.dart'; -part 'src/source.dart'; -part 'src/timestamp.dart'; +export 'src/blob.dart'; +export 'src/document_snapshot.dart'; +export 'src/field_path.dart'; +export 'src/geo_point.dart'; +export 'src/snapshot_metadata.dart'; +export 'src/source.dart'; +export 'src/timestamp.dart'; + +// Platform interface parts +export 'src/platform_interface/collection_reference.dart'; +export 'src/platform_interface/document_change.dart'; +export 'src/platform_interface/document_reference.dart'; +export 'src/platform_interface/field_value.dart'; +export 'src/platform_interface/field_value_factory.dart'; +export 'src/platform_interface/query.dart'; +export 'src/platform_interface/query_snapshot.dart'; +export 'src/platform_interface/transaction.dart'; +export 'src/platform_interface/write_batch.dart'; /// Defines an interface to work with [FirestorePlatform] on web and mobile abstract class FirestorePlatform extends PlatformInterface { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index def15e443561..face4847e71f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -1,4 +1,7 @@ -part of cloud_firestore_platform_interface; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:collection/collection.dart'; /// Represents binary data stored in [Uint8List]. class Blob { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index 6b1d0e9d15d4..fb5fee78a910 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -1,8 +1,7 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// Contains data read from a document in your Firestore /// database. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart index 0ce8b0b0def2..55a25f3ce250 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/field_path.dart @@ -1,8 +1,7 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; +import 'internal/field_path_type.dart'; /// A [FieldPath] refers to a field in a document. class FieldPath { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart index cae3227690df..109c17d47d75 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/geo_point.dart @@ -1,8 +1,7 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; +import 'dart:ui'; /// Represents a geographical point by its longitude and latitude class GeoPoint { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart index 1bce1e165ff3..e880892a7e8a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/collection_reference.dart @@ -1,8 +1,9 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. 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'; -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index 56d0699de1ab..abd81c5ff9d9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -1,8 +1,9 @@ // Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; -part of cloud_firestore_platform_interface; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// An enumeration of document change types. enum DocumentChangeType { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 67bc61600ece..5d154782be30 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -1,4 +1,9 @@ -part of cloud_firestore_platform_interface; +import 'dart:async'; +import 'dart:ui'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// A [DocumentReferencePlatform] refers to a document location in a Firestore database /// and can be used to write, read, or listen to the location. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 4eee4cc96df8..07ec70865d86 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -2,7 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// A class to define an interface that's required /// for building platform-specific implementation diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 9ebce5991ffb..9b626286ed88 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -1,4 +1,7 @@ -part of cloud_firestore_platform_interface; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// Sentinel values that can be used when writing document fields with set() or /// update(). diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index eaac7c1a728f..d79bba697734 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -2,7 +2,13 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:meta/meta.dart' show required; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// Represents a query over the data at a particular location. abstract class QueryPlatform extends PlatformInterface { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 7b88dae1ac2f..5d93083def93 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -2,7 +2,9 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// A QuerySnapshot contains zero or more DocumentSnapshot objects. class QuerySnapshotPlatform extends PlatformInterface { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 53fc445e3322..628338453339 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -2,7 +2,13 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:meta/meta.dart' show visibleForTesting; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// The TransactionHandler may be executed multiple times, it should be able /// to handle multiple executions. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart index 10056cb52f69..e7b4d113139f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/write_batch.dart @@ -1,8 +1,11 @@ // Copyright 2018, the Chromium project authors. Please see the AUTHORS file // for details. 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'; -part of cloud_firestore_platform_interface; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; /// A [WriteBatch] is a series of write operations to be performed as one unit. /// diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart index 5a287bcf0c82..54cc5df7f6e3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; - /// Metadata about a snapshot, describing the state of the snapshot. class SnapshotMetadata { /// Create an instance of [SnapshotMetadata] diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart index 88b312f55db9..c7823e6d3bc5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -part of cloud_firestore_platform_interface; - /// An enumeration of firestore source types. enum Source { /// Causes Firestore to try to retrieve an up-to-date (server-retrieved) snapshot, but fall back to diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart index 26411f2e680d..1172add1e18b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/timestamp.dart @@ -1,8 +1,7 @@ // Copyright 2018, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore_platform_interface; +import 'dart:ui'; const int _kThousand = 1000; const int _kMillion = 1000000; From e40a1c3d5d24546376af5f9c27be0f4d63c550fe Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 16:02:33 -0800 Subject: [PATCH 125/144] Add copyright notices everywhere. --- .../cloud_firestore/lib/src/utils/codec_utility.dart | 4 ++++ .../cloud_firestore/lib/src/utils/platform_utils.dart | 4 ++++ .../lib/cloud_firestore_platform_interface.dart | 4 ++++ .../cloud_firestore_platform_interface/lib/src/blob.dart | 4 ++++ .../method_channel/method_channel_field_value_factory.dart | 4 ++++ .../lib/src/platform_interface/document_reference.dart | 4 ++++ .../lib/src/platform_interface/field_value_factory.dart | 4 ++++ .../test/document_reference_test.dart | 4 ++++ .../test/field_value_test.dart | 4 ++++ .../test/method_channel_collection_reference_test.dart | 4 ++++ .../test/method_channel_document_reference.dart | 4 ++++ .../test/method_channel_field_value_factory_test.dart | 4 ++++ .../cloud_firestore_platform_interface/test/query_test.dart | 4 ++++ .../cloud_firestore_platform_interface/test/test_common.dart | 4 ++++ .../test/transaction_test.dart | 4 ++++ .../cloud_firestore_web/lib/firestore_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/collection_reference_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/document_reference_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/field_value_factory_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/field_value_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/query_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/transaction_web.dart | 4 ++++ .../cloud_firestore_web/lib/src/utils/codec_utility.dart | 4 ++++ .../lib/src/utils/document_reference_utils.dart | 4 ++++ .../cloud_firestore_web/lib/src/write_batch_web.dart | 4 ++++ .../cloud_firestore_web/test/codec_utility_test.dart | 4 ++++ .../test/collection_reference_web_test.dart | 4 ++++ .../cloud_firestore_web/test/document_reference_web_test.dart | 4 ++++ .../test/field_value_factory_web_test.dart | 4 ++++ .../cloud_firestore_web/test/query_web_test.dart | 4 ++++ .../cloud_firestore/cloud_firestore_web/test/test_common.dart | 4 ++++ .../cloud_firestore_web/test/transaction_web_test.dart | 4 ++++ .../cloud_firestore_web/test/write_batch_web_test.dart | 4 ++++ 33 files changed, 132 insertions(+) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart index ca56976604d0..bd090bab5eb0 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/codec_utility.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + part of cloud_firestore; class _CodecUtility { diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart index ee8637c071a0..e717b912d017 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + part of cloud_firestore; class _PlatformUtils { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 57ef0d0c6a9d..2aa8660548f0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + library cloud_firestore_platform_interface; import 'dart:async'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart index face4847e71f..d7a7befd9e45 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/blob.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. 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:typed_data'; import 'dart:ui'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 001bf496b819..961ba949fc7f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:flutter/services.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index 5d154782be30..b6a133bec1df 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. 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 'dart:ui'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 9b626286ed88..54723dbf154e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart index db51ad4b7f86..155d03cbbaf2 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart index 021d8f208b41..1611bb91f3d0 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart index 0083f8db1ce7..1aaa55581197 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index da50d20a5b85..265a24455c2d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart index 201c993a808a..e3c85736010c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart index d90c224f6130..629ee5f9d8b5 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index 3998edf98dde..56ec01217045 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index ab57fad4bbfc..8663118383eb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart index bd1d61094b2c..0558b9b28597 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firebase.dart' as firebase; import 'package:firebase/firestore.dart' show Firestore, Settings; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index ede6440b89e0..6887c1a3a362 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; import 'package:meta/meta.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart index 1d7ad626292e..1358d43e8359 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart index 3ece3185fcf4..e0957203c734 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; import 'package:js/js_util.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart index 92d097dfb607..659c1e3b73c7 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index a31618028b4f..581bcb46fac4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 28687cc744c9..612a6075f45f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index e81859b18962..87e9cd678bf9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart index 95f9429452e2..9ded38ee588c 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart index b13fbe480afa..7d76b20b8fda 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index a3e01fc3d8b0..c2a8c2d37dd8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn("chrome") import 'dart:typed_data'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index d139cb6cdf05..7399a2fd1ebc 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn('chrome') import 'dart:js' as js; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart index 65cc64f72905..327b25516a38 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn('chrome') import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/src/document_reference_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart index 8535616d05ed..3efe86c06b1f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index 0bd03b0e32ff..0f853317e7c4 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 3a76de40ac4f..147aee3009dd 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. 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:js' as js; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:cloud_firestore_web/firestore_web.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart index 2268bc027044..e7f243862cbe 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn("chrome") import 'package:cloud_firestore_web/src/transaction_web.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart index 4c6a4aafc2b1..b947386de664 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + @TestOn("chrome") import 'package:cloud_firestore_web/src/write_batch_web.dart'; import 'package:flutter_test/flutter_test.dart'; From 6f749292194ac76ec351565b1a6d6c7598a99102 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 16:23:46 -0800 Subject: [PATCH 126/144] Ensure FieldValue extends Platform, not implements. --- .../cloud_firestore/cloud_firestore/lib/src/field_value.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 58bfaceadc50..f4451af424ac 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -6,10 +6,10 @@ part of cloud_firestore; /// Sentinel values that can be used when writing document fields with set() or /// update(). -class FieldValue implements platform.FieldValuePlatform { +class FieldValue extends platform.FieldValuePlatform { platform.FieldValuePlatform _delegate; - FieldValue._(this._delegate) { + FieldValue._(this._delegate) : super(_delegate.type, _delegate.value) { platform.FieldValuePlatform.verifyExtends(_delegate); } From 192ad6679eedc3372a32effcd5ed266358f19c00 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 16:41:00 -0800 Subject: [PATCH 127/144] Remove implements web.FieldValue from FieldValueWeb, since the web.FieldValue API actually happens in the Factory. --- .../cloud_firestore_web/lib/src/field_value_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart index 659c1e3b73c7..c3003c15e255 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -7,7 +7,7 @@ import 'package:firebase/firestore.dart' as web; /// Implementation of [FieldValuePlatform] that is compatible with /// firestore web plugin -class FieldValueWeb extends FieldValuePlatform implements web.FieldValue { +class FieldValueWeb extends FieldValuePlatform { /// The js-interop delegate for this [FieldValuePlatform] web.FieldValue delegate; From ff5561e3d54fbdf8b5afef55804fa436c950699e Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 17:03:20 -0800 Subject: [PATCH 128/144] Remove `serverDelegates` from `FieldValuePlatform`, and convert to a Maps MethodChannel util. Move getSourceString as a Source MethodChannel util. --- .../method_channel_document_reference.dart | 5 +++-- .../method_channel/method_channel_query.dart | 1 + .../method_channel_transaction.dart | 5 +++-- .../method_channel_write_batch.dart | 5 +++-- .../lib/src/method_channel/utils/maps.dart | 20 +++++++++++++++++++ .../lib/src/method_channel/utils/source.dart | 17 ++++++++++++++++ .../src/platform_interface/field_value.dart | 17 ---------------- .../lib/src/source.dart | 12 ----------- .../test/field_value_test.dart | 10 ++++++---- 9 files changed, 53 insertions(+), 39 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index a108a60537a6..2194786d9748 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -8,6 +8,7 @@ import 'package:flutter/services.dart'; import 'method_channel_firestore.dart'; import 'utils/maps.dart'; +import 'utils/source.dart'; /// A [MethodChannelDocumentReference] is an implementation of /// [DocumentReferencePlatform] that uses [MethodChannel] to communicate with @@ -26,7 +27,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { { 'app': firestore.app.name, 'path': path, - 'data': FieldValuePlatform.serverDelegates(data), + 'data': unwrapFieldValueInterfaceToPlatformType(data), 'options': {'merge': merge}, }, ); @@ -39,7 +40,7 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { { 'app': firestore.app.name, 'path': path, - 'data': FieldValuePlatform.serverDelegates(data), + 'data': unwrapFieldValueInterfaceToPlatformType(data), }, ); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index c59582b42da5..5be461883311 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -11,6 +11,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'method_channel_firestore.dart'; import 'method_channel_query_snapshot.dart'; +import 'utils/source.dart'; /// Represents a query over the data at a particular location. class MethodChannelQuery extends QueryPlatform { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index abb6a86975af..1ca621450f25 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -9,6 +9,7 @@ import 'package:flutter/services.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'method_channel_firestore.dart'; +import 'utils/maps.dart'; /// An implementation of [TransactionPlatform] which uses [MethodChannel] to /// communication with native plugin @@ -66,7 +67,7 @@ class MethodChannelTransaction extends TransactionPlatform { 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, - 'data': FieldValuePlatform.serverDelegates(data), + 'data': unwrapFieldValueInterfaceToPlatformType(data), }); } @@ -80,7 +81,7 @@ class MethodChannelTransaction extends TransactionPlatform { 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, - 'data': FieldValuePlatform.serverDelegates(data), + 'data': unwrapFieldValueInterfaceToPlatformType(data), }); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index 5bd5ae60298c..ecec2fd27785 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'method_channel_firestore.dart'; +import 'utils/maps.dart'; /// A [MethodChannelWriteBatch] is a series of write operations to be performed as one unit. /// @@ -70,7 +71,7 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { 'app': _firestore.app.name, 'handle': handle, 'path': document.path, - 'data': FieldValuePlatform.serverDelegates(data), + 'data': unwrapFieldValueInterfaceToPlatformType(data), 'options': {'merge': merge}, }, ), @@ -93,7 +94,7 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { 'app': _firestore.app.name, 'handle': handle, 'path': document.path, - 'data': FieldValuePlatform.serverDelegates(data) + 'data': unwrapFieldValueInterfaceToPlatformType(data) }, ), ); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart index 038c74633892..0b4aeceea671 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart @@ -2,6 +2,26 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:cloud_firestore_platform_interface/src/platform_interface/field_value.dart'; + /// Casts a Map to Map Map asStringKeyedMap(Map map) => map?.cast(); + +/// Replaces items with type [FieldValueInterface] with implementation type +/// such as [FieldValuePlatform] +Map unwrapFieldValueInterfaceToPlatformType(Map data) { + if (data == null) { + return null; + } + Map output = Map.from(data); + output.updateAll((key, value) { + if (value is FieldValueInterface && + value.instance is FieldValuePlatform) { + return value.instance; + } else { + return value; + } + }); + return output; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart new file mode 100644 index 000000000000..c454fdb84736 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/source.dart @@ -0,0 +1,17 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/src/source.dart'; + +/// Converts [Source] to [String] +String getSourceString(Source source) { + assert(source != null); + if (source == Source.server) { + return 'server'; + } + if (source == Source.cache) { + return 'cache'; + } + return 'default'; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index 07ec70865d86..c92e6ad3209e 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -22,23 +22,6 @@ abstract class FieldValueInterface { /// Platform Interface of a FieldValue; implementation for [FieldValueInterface] class FieldValuePlatform extends PlatformInterface implements FieldValueInterface { - /// Replaces items with type [FieldValueInterface] with implementation type - /// such as [FieldValuePlatform] - static Map serverDelegates(Map data) { - if (data == null) { - return null; - } - Map output = Map.from(data); - output.updateAll((key, value) { - if (value is FieldValueInterface && - value.instance is FieldValuePlatform) { - return value.instance; - } else { - return value; - } - }); - return output; - } static final Object _token = Object(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart index c7823e6d3bc5..dfde83b87d82 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/source.dart @@ -21,15 +21,3 @@ enum Source { /// [QuerySnapshotPlatform] with no documents. cache, } - -/// Converts [Source] to [String] -String getSourceString(Source source) { - assert(source != null); - if (source == Source.server) { - return 'server'; - } - if (source == Source.cache) { - return 'cache'; - } - return 'default'; -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart index 1611bb91f3d0..67136d9832f1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart @@ -6,16 +6,18 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/utils/maps.dart'; + class MockFieldValue extends Mock implements FieldValuePlatform {} void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group("$FieldValuePlatform()", () { - test("serverDelegates", () { - expect(FieldValuePlatform.serverDelegates(null), isNull); + group("$unwrapFieldValueInterfaceToPlatformType()", () { + test("unwrapFieldValueInterfaces", () { + expect(unwrapFieldValueInterfaceToPlatformType(null), isNull); final mockFieldValue = MockFieldValue(); - FieldValuePlatform.serverDelegates({"item": mockFieldValue}); + unwrapFieldValueInterfaceToPlatformType({"item": mockFieldValue}); verify(mockFieldValue.instance); }); }); From b4de78545130110b2b452a65ddcec1c524073fdb Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 17:07:06 -0800 Subject: [PATCH 129/144] dartfmt --- .../lib/src/method_channel/utils/maps.dart | 6 +++--- .../lib/src/platform_interface/field_value.dart | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart index 0b4aeceea671..bcd8dcb554d7 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart @@ -10,14 +10,14 @@ Map asStringKeyedMap(Map map) => /// Replaces items with type [FieldValueInterface] with implementation type /// such as [FieldValuePlatform] -Map unwrapFieldValueInterfaceToPlatformType(Map data) { +Map unwrapFieldValueInterfaceToPlatformType( + Map data) { if (data == null) { return null; } Map output = Map.from(data); output.updateAll((key, value) { - if (value is FieldValueInterface && - value.instance is FieldValuePlatform) { + if (value is FieldValueInterface && value.instance is FieldValuePlatform) { return value.instance; } else { return value; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart index c92e6ad3209e..b18ca2c75558 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart @@ -22,7 +22,6 @@ abstract class FieldValueInterface { /// Platform Interface of a FieldValue; implementation for [FieldValueInterface] class FieldValuePlatform extends PlatformInterface implements FieldValueInterface { - static final Object _token = Object(); /// Throws an [AssertionError] if [instance] does not extend From d69f67e65225eff013b9a358f3e893c21ec3af63 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 17:11:42 -0800 Subject: [PATCH 130/144] Remove appName() from FirestorePlatform. Reimplement hashCode with app.name instead. --- .../lib/cloud_firestore_platform_interface.dart | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 2aa8660548f0..1c48ef91fa92 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -80,11 +80,6 @@ abstract class FirestorePlatform extends PlatformInterface { throw UnimplementedError("withApp() not implemented"); } - /// Firebase app name - String appName() { - throw UnimplementedError("appName() not implemented"); - } - /// Gets a [CollectionReferencePlatform] for the specified Firestore path. CollectionReferencePlatform collection(String path) { throw UnimplementedError('collection() is not implemented'); @@ -157,7 +152,7 @@ abstract class FirestorePlatform extends PlatformInterface { } @override - int get hashCode => appName().hashCode; + int get hashCode => app.name.hashCode; @override bool operator ==(dynamic o) => o is FirestorePlatform && o.app == app; From 7009ef6f88318be54fefb03de83f7cb719dd47e1 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 17:36:44 -0800 Subject: [PATCH 131/144] Use Source and DocumentChangeType enums from PlatformInterface. Rename SnapshotMetadata and DocumentSnapshot in PlatformInterface to SnapshotMetadataPlatform and DocumentSnapshotPlatform so they don't collide with class names exported by the core plugin. --- .../cloud_firestore/lib/cloud_firestore.dart | 3 +- .../lib/src/document_change.dart | 16 +-------- .../lib/src/document_reference.dart | 4 +-- .../lib/src/document_snapshot.dart | 2 +- .../cloud_firestore/lib/src/query.dart | 4 +-- .../lib/src/snapshot_metadata.dart | 2 +- .../cloud_firestore/lib/src/source.dart | 25 -------------- .../lib/src/utils/platform_utils.dart | 33 ++----------------- .../lib/src/document_snapshot.dart | 11 ++++--- .../method_channel_document_change.dart | 4 +-- .../method_channel_document_reference.dart | 15 +++++---- .../method_channel_firestore.dart | 9 ++--- .../method_channel/method_channel_query.dart | 8 ++--- .../method_channel_query_snapshot.dart | 10 +++--- .../method_channel_transaction.dart | 6 ++-- .../platform_interface/document_change.dart | 2 +- .../document_reference.dart | 5 +-- .../lib/src/platform_interface/query.dart | 8 ++--- .../platform_interface/query_snapshot.dart | 4 +-- .../src/platform_interface/transaction.dart | 7 ++-- .../lib/src/snapshot_metadata.dart | 6 ++-- .../method_channel_cloud_firestore_test.dart | 24 +++++++------- .../lib/src/collection_reference_web.dart | 8 ++--- .../lib/src/document_reference_web.dart | 4 +-- .../lib/src/query_web.dart | 13 ++++---- .../lib/src/transaction_web.dart | 2 +- .../src/utils/document_reference_utils.dart | 8 ++--- .../cloud_firestore_web/test/test_common.dart | 2 +- 28 files changed, 94 insertions(+), 151 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/lib/src/source.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 19f8edcbdca3..298ab4efaf25 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -14,7 +14,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:meta/meta.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' - show FieldPath, Blob, GeoPoint, Timestamp; + show FieldPath, Blob, GeoPoint, Timestamp, Source, DocumentChangeType; part 'src/collection_reference.dart'; part 'src/document_change.dart'; @@ -29,4 +29,3 @@ part 'src/utils/codec_utility.dart'; part 'src/snapshot_metadata.dart'; part 'src/transaction.dart'; part 'src/write_batch.dart'; -part 'src/source.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart index d26018145684..3f94fa940672 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_change.dart @@ -4,20 +4,6 @@ part of cloud_firestore; -/// An enumeration of document change types. -enum DocumentChangeType { - /// Indicates a new document was added to the set of documents matching the - /// query. - added, - - /// Indicates a document within the query was modified. - modified, - - /// Indicates a document within the query was removed (either deleted or no - /// longer matches the query. - removed, -} - /// A DocumentChange represents a change to the documents matching a query. /// /// It contains the document affected and the type of change that occurred @@ -31,7 +17,7 @@ class DocumentChange { } /// The type of change that occurred (added, modified, or removed). - DocumentChangeType get type => _PlatformUtils.fromPlatform(_delegate.type); + platform.DocumentChangeType get type => _delegate.type; /// The index of the changed document in the result set immediately prior to /// this [DocumentChange] (i.e. supposing that all prior DocumentChange objects diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index f803ff36c0b8..cea1c65494ca 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -63,9 +63,9 @@ class DocumentReference { /// Reads the document referenced by this [DocumentReference]. /// /// If no document exists, the read will return null. - Future get({Source source = Source.serverAndCache}) async { + Future get({platform.Source source = platform.Source.serverAndCache,}) async { return DocumentSnapshot._( - await _delegate.get(source: _PlatformUtils.toPlatformSource(source)), + await _delegate.get(source: source), firestore); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart index 9697b96ea515..220efff3960b 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_snapshot.dart @@ -10,7 +10,7 @@ part of cloud_firestore; /// The data can be extracted with the data property or by using subscript /// syntax to access a specific field. class DocumentSnapshot { - platform.DocumentSnapshot _delegate; + platform.DocumentSnapshotPlatform _delegate; final Firestore _firestore; DocumentSnapshot._(this._delegate, this._firestore); diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index 9ad2a24fe6fd..a883dd6629db 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -31,10 +31,10 @@ class Query { /// Fetch the documents for this query Future getDocuments( - {Source source = Source.serverAndCache}) async { + {platform.Source source = platform.Source.serverAndCache,}) async { assert(source != null); final docs = await _delegate.getDocuments( - source: _PlatformUtils.toPlatformSource(source)); + source: source); return QuerySnapshot._(docs, firestore); } diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart index e0017ae93722..b1e8b0c83705 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/snapshot_metadata.dart @@ -6,7 +6,7 @@ part of cloud_firestore; /// Metadata about a snapshot, describing the state of the snapshot. class SnapshotMetadata { - platform.SnapshotMetadata _delegate; + platform.SnapshotMetadataPlatform _delegate; SnapshotMetadata._(this._delegate); /// Whether the snapshot contains the result of local writes that have not yet diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/source.dart b/packages/cloud_firestore/cloud_firestore/lib/src/source.dart deleted file mode 100644 index 012762b6a84b..000000000000 --- a/packages/cloud_firestore/cloud_firestore/lib/src/source.dart +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -part of cloud_firestore; - -/// An enumeration of firestore source types. -enum Source { - /// Causes Firestore to try to retrieve an up-to-date (server-retrieved) snapshot, but fall back to - /// returning cached data if the server can't be reached. - serverAndCache, - - /// Causes Firestore to avoid the cache, generating an error if the server cannot be reached. Note - /// that the cache will still be updated if the server request succeeds. Also note that - /// latency-compensation still takes effect, so any pending write operations will be visible in the - /// returned data (merged into the server-provided data). - server, - - /// Causes Firestore to immediately return a value from the cache, ignoring the server completely - /// (implying that the returned value may be stale with respect to the value on the server). If - /// there is no data in the cache to satisfy the [get()] or [getDocuments()] call, - /// [DocumentReference.get()] will return an error and [Query.getDocuments()] will return an empty - /// [QuerySnapshot] with no documents. - cache, -} diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart index e717b912d017..c9880257c67a 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/utils/platform_utils.dart @@ -5,39 +5,12 @@ part of cloud_firestore; class _PlatformUtils { - static DocumentChangeType fromPlatform( - platform.DocumentChangeType platformChange) { - switch (platformChange) { - case platform.DocumentChangeType.added: - return DocumentChangeType.added; - case platform.DocumentChangeType.modified: - return DocumentChangeType.modified; - case platform.DocumentChangeType.removed: - return DocumentChangeType.removed; - default: - throw ArgumentError("Invalud change type"); - } - } - - static platform.Source toPlatformSource(Source source) { - switch (source) { - case Source.cache: - return platform.Source.cache; - case Source.server: - return platform.Source.server; - case Source.serverAndCache: - return platform.Source.serverAndCache; - default: - throw ArgumentError("Invalid source value"); - } - } - - static platform.DocumentSnapshot toPlatformDocumentSnapshot( + static platform.DocumentSnapshotPlatform toPlatformDocumentSnapshot( DocumentSnapshot documentSnapshot) => - platform.DocumentSnapshot( + platform.DocumentSnapshotPlatform( documentSnapshot.reference.path, documentSnapshot.data, - platform.SnapshotMetadata( + platform.SnapshotMetadataPlatform( documentSnapshot.metadata.hasPendingWrites, documentSnapshot.metadata.isFromCache, ), diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart index fb5fee78a910..7a838a08d100 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/document_snapshot.dart @@ -8,13 +8,14 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte /// /// The data can be extracted with the [data] property or by using subscript /// syntax to access a specific field. -class DocumentSnapshot { - /// Constructs a [DocumentSnapshot] using the provided [FirestorePlatform]. - DocumentSnapshot(this._path, this.data, this.metadata, this.firestore); +class DocumentSnapshotPlatform { + /// Constructs a [DocumentSnapshotPlatform] using the provided [FirestorePlatform]. + DocumentSnapshotPlatform( + this._path, this.data, this.metadata, this.firestore); final String _path; - /// The [FirestorePlatform] used to produce this [DocumentSnapshot]. + /// The [FirestorePlatform] used to produce this [DocumentSnapshotPlatform]. final FirestorePlatform firestore; /// The reference that produced this snapshot. @@ -25,7 +26,7 @@ class DocumentSnapshot { /// Metadata about this snapshot concerning its source and if it has local /// modifications. - final SnapshotMetadata metadata; + final SnapshotMetadataPlatform metadata; /// Reads individual values from the snapshot. dynamic operator [](String key) => data[key]; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart index 972bd6282ea4..3cd45d0b876a 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_change.dart @@ -18,10 +18,10 @@ class MethodChannelDocumentChange extends DocumentChangePlatform { }), data['oldIndex'], data['newIndex'], - DocumentSnapshot( + DocumentSnapshotPlatform( data['path'], asStringKeyedMap(data['document']), - SnapshotMetadata(data['metadata']['hasPendingWrites'], + SnapshotMetadataPlatform(data['metadata']['hasPendingWrites'], data['metadata']['isFromCache']), firestore, )); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index 2194786d9748..c8aac67397af 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -46,7 +46,8 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { } @override - Future get({Source source = Source.serverAndCache}) async { + Future get( + {Source source = Source.serverAndCache}) async { final Map data = await MethodChannelFirestore.channel.invokeMapMethod( 'DocumentReference#get', @@ -56,10 +57,10 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { 'source': getSourceString(source), }, ); - return DocumentSnapshot( + return DocumentSnapshotPlatform( data['path'], asStringKeyedMap(data['data']), - SnapshotMetadata(data['metadata']['hasPendingWrites'], + SnapshotMetadataPlatform(data['metadata']['hasPendingWrites'], data['metadata']['isFromCache']), firestore, ); @@ -75,13 +76,15 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { // TODO(jackson): Reduce code duplication with [Query] @override - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots( + {bool includeMetadataChanges = false}) { assert(includeMetadataChanges != null); Future _handle; // It's fine to let the StreamController be garbage collected once all the // subscribers have cancelled; this analyzer warning is safe to ignore. - StreamController controller; // ignore: close_sinks - controller = StreamController.broadcast( + StreamController + controller; // ignore: close_sinks + controller = StreamController.broadcast( onListen: () { _handle = MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#addSnapshotListener', diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index e46947b6709a..c86075e90ade 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -30,10 +30,11 @@ class MethodChannelFirestore extends FirestorePlatform { MethodChannelQuerySnapshot(call.arguments, this); queryObservers[call.arguments['handle']].add(snapshot); } else if (call.method == 'DocumentSnapshot') { - final DocumentSnapshot snapshot = DocumentSnapshot( + final DocumentSnapshotPlatform snapshot = DocumentSnapshotPlatform( call.arguments['path'], asStringKeyedMap(call.arguments['data']), - SnapshotMetadata(call.arguments['metadata']['hasPendingWrites'], + SnapshotMetadataPlatform( + call.arguments['metadata']['hasPendingWrites'], call.arguments['metadata']['isFromCache']), this, ); @@ -72,8 +73,8 @@ class MethodChannelFirestore extends FirestorePlatform { /// A map containing all the pending Document Observers, keyed by their id. /// This is shared amongst all [MethodChannelDocumentReference] objects, and the /// `DocumentSnapshot` `MethodCall` handler initialized in the constructor of this class. - static final Map> documentObservers = - >{}; + static final Map> + documentObservers = >{}; static final Map _transactionHandlers = {}; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart index 5be461883311..31827afacd03 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query.dart @@ -193,7 +193,7 @@ class MethodChannelQuery extends QueryPlatform { } @override - QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -215,7 +215,7 @@ class MethodChannelQuery extends QueryPlatform { } @override - QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('startAfter')); assert(!parameters.containsKey('startAt')); @@ -257,7 +257,7 @@ class MethodChannelQuery extends QueryPlatform { } @override - QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); @@ -290,7 +290,7 @@ class MethodChannelQuery extends QueryPlatform { } @override - QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { assert(documentSnapshot != null); assert(!parameters.containsKey('endBefore')); assert(!parameters.containsKey('endAt')); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart index de6b3c75963a..ca1162c03ca3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_query_snapshot.dart @@ -6,18 +6,18 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'method_channel_document_change.dart'; import 'utils/maps.dart'; -/// Contains zero or more [DocumentSnapshot] objects. +/// Contains zero or more [DocumentSnapshotPlatform] objects. class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { /// Creates a [MethodChannelQuerySnapshot] from the given [data] MethodChannelQuerySnapshot( Map data, FirestorePlatform firestore) : super( - List.generate(data['documents'].length, + List.generate(data['documents'].length, (int index) { - return DocumentSnapshot( + return DocumentSnapshotPlatform( data['paths'][index], asStringKeyedMap(data['documents'][index]), - SnapshotMetadata( + SnapshotMetadataPlatform( data['metadatas'][index]['hasPendingWrites'], data['metadatas'][index]['isFromCache'], ), @@ -31,7 +31,7 @@ class MethodChannelQuerySnapshot extends QuerySnapshotPlatform { firestore, ); }), - SnapshotMetadata( + SnapshotMetadataPlatform( data['metadata']['hasPendingWrites'], data['metadata']['isFromCache'], )); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index 1ca621450f25..8e72971b2541 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -26,7 +26,7 @@ class MethodChannelTransaction extends TransactionPlatform { : FirestorePlatform.instanceFor(app: FirebaseApp(name: appName))); @override - Future doGet( + Future doGet( DocumentReferencePlatform documentReference, ) async { final Map result = await MethodChannelFirestore.channel @@ -36,10 +36,10 @@ class MethodChannelTransaction extends TransactionPlatform { 'path': documentReference.path, }); if (result != null) { - return DocumentSnapshot( + return DocumentSnapshotPlatform( documentReference.path, result['data']?.cast(), - SnapshotMetadata(result['metadata']['hasPendingWrites'], + SnapshotMetadataPlatform(result['metadata']['hasPendingWrites'], result['metadata']['isFromCache']), firestore); } else { diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart index abd81c5ff9d9..217c0a81979d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_change.dart @@ -62,5 +62,5 @@ class DocumentChangePlatform extends PlatformInterface { final int newIndex; /// The document affected by this change. - final DocumentSnapshot document; + final DocumentSnapshotPlatform document; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart index b6a133bec1df..33c51d79b30d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/document_reference.dart @@ -88,7 +88,7 @@ abstract class DocumentReferencePlatform extends PlatformInterface { /// Reads the document referenced by this [DocumentReferencePlatform]. /// /// If no document exists, the read will return null. - Future get({ + Future get({ Source source = Source.serverAndCache, }) async { throw UnimplementedError("get() is not implemented"); @@ -106,7 +106,8 @@ abstract class DocumentReferencePlatform extends PlatformInterface { } /// Notifies of documents at this location - Stream snapshots({bool includeMetadataChanges = false}) { + Stream snapshots( + {bool includeMetadataChanges = false}) { throw UnimplementedError("snapshots() is not implemented"); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart index d79bba697734..da35b62259a8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query.dart @@ -143,7 +143,7 @@ abstract class QueryPlatform extends PlatformInterface { /// * [endAfterDocument] for a query that ends after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { throw UnimplementedError("startAfterDocument() is not implemented"); } @@ -161,7 +161,7 @@ abstract class QueryPlatform extends PlatformInterface { /// * [startAfterDocument] for a query that starts after a document. /// * [endAtDocument] for a query that ends at a document. /// * [endBeforeDocument] for a query that ends before a document. - QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { throw UnimplementedError("startAtDocument() is not implemented"); } @@ -203,7 +203,7 @@ abstract class QueryPlatform extends PlatformInterface { /// * [startAfterDocument] for a query that starts after a document. /// * [startAtDocument] for a query that starts at a document. /// * [endBeforeDocument] for a query that ends before a document. - QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { throw UnimplementedError("endAtDocument() is not implemented"); } @@ -233,7 +233,7 @@ abstract class QueryPlatform extends PlatformInterface { /// * [startAfterDocument] for a query that starts after document. /// * [startAtDocument] for a query that starts at a document. /// * [endAtDocument] for a query that ends at a document. - QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { throw UnimplementedError("endBeforeDocument() is not implemented"); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart index 5d93083def93..a3ae8a4880c6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/query_snapshot.dart @@ -28,12 +28,12 @@ class QuerySnapshotPlatform extends PlatformInterface { } /// Gets a list of all the documents included in this snapshot - final List documents; + final List documents; /// An array of the documents that changed since the last snapshot. If this /// is the first snapshot, all documents will be in the list as Added changes. final List documentChanges; /// Metadata for the document - final SnapshotMetadata metadata; + final SnapshotMetadataPlatform metadata; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index 628338453339..f82a3c4269f6 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -41,8 +41,9 @@ abstract class TransactionPlatform extends PlatformInterface { Future finish() => Future.wait(_pendingResults); /// Reads the document referenced by the provided DocumentReference. - Future get(DocumentReferencePlatform documentReference) { - final Future result = doGet(documentReference); + Future get( + DocumentReferencePlatform documentReference) { + final Future result = doGet(documentReference); _pendingResults.add(result); return result; } @@ -51,7 +52,7 @@ abstract class TransactionPlatform extends PlatformInterface { /// This is here so it can be overridden by implementations that do NOT /// handle returned futures automatically, like the [MethodChannelTransaction]. /// Does not affect the _pendingResults. - Future doGet( + Future doGet( DocumentReferencePlatform documentReference, ) async { throw UnimplementedError("get() not implemented"); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart index 54cc5df7f6e3..f03c075e6566 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/snapshot_metadata.dart @@ -3,9 +3,9 @@ // BSD-style license that can be found in the LICENSE file. /// Metadata about a snapshot, describing the state of the snapshot. -class SnapshotMetadata { - /// Create an instance of [SnapshotMetadata] - SnapshotMetadata(this.hasPendingWrites, this.isFromCache); +class SnapshotMetadataPlatform { + /// Create an instance of [SnapshotMetadataPlatform] + SnapshotMetadataPlatform(this.hasPendingWrites, this.isFromCache); /// Whether the snapshot contains the result of local writes that have not yet /// been committed to the backend. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 7fc4938d3968..6a9bc33772c6 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -223,7 +223,7 @@ void main() { test('get', () async { final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); - final DocumentSnapshot snapshot = + final DocumentSnapshotPlatform snapshot = await transaction.get(documentReference); expect(snapshot.reference.firestore, firestore); expect(log, [ @@ -264,7 +264,8 @@ void main() { test('update', () async { final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); - final DocumentSnapshot documentSnapshot = await documentReference.get(); + final DocumentSnapshotPlatform documentSnapshot = + await documentReference.get(); final Map data = documentSnapshot.data; data['key2'] = 'val2'; await transaction.set(documentReference, data); @@ -286,7 +287,8 @@ void main() { test('set', () async { final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); - final DocumentSnapshot documentSnapshot = await documentReference.get(); + final DocumentSnapshotPlatform documentSnapshot = + await documentReference.get(); final Map data = documentSnapshot.data; data['key2'] = 'val2'; await transaction.set(documentReference, data); @@ -344,7 +346,7 @@ void main() { final QuerySnapshotPlatform snapshot = await collectionReference .snapshots(includeMetadataChanges: true) .first; - final DocumentSnapshot document = snapshot.documents[0]; + final DocumentSnapshotPlatform document = snapshot.documents[0]; expect(document.documentID, equals('0')); expect(document.reference.path, equals('foo/0')); expect(document.data, equals(kMockDocumentSnapshotData)); @@ -548,7 +550,7 @@ void main() { group('DocumentReference', () { test('listen', () async { - final DocumentSnapshot snapshot = await firestore + final DocumentSnapshotPlatform snapshot = await firestore .document('path/to/foo') .snapshots(includeMetadataChanges: true) .first; @@ -647,7 +649,7 @@ void main() { ); }); test('get', () async { - final DocumentSnapshot snapshot = + final DocumentSnapshotPlatform snapshot = await collectionReference.document('bar').get(source: Source.cache); expect(snapshot.reference.firestore, firestore); expect( @@ -669,7 +671,7 @@ void main() { expect(snapshot.data['key1'], equals('val1')); expect(snapshot.exists, isTrue); - final DocumentSnapshot snapshot2 = await collectionReference + final DocumentSnapshotPlatform snapshot2 = await collectionReference .document('notExists') .get(source: Source.serverAndCache); expect(snapshot2.data, isNull); @@ -714,7 +716,7 @@ void main() { equals(kMockSnapshotMetadata['hasPendingWrites'])); expect(snapshot.metadata.isFromCache, equals(kMockSnapshotMetadata['isFromCache'])); - DocumentSnapshot document = snapshot.documents.first; + DocumentSnapshotPlatform document = snapshot.documents.first; expect(document.documentID, equals('0')); expect(document.reference.path, equals('foo/0')); expect(document.data, equals(kMockDocumentSnapshotData)); @@ -886,7 +888,7 @@ void main() { equals(kMockSnapshotMetadata['hasPendingWrites'])); expect(snapshot.metadata.isFromCache, equals(kMockSnapshotMetadata['isFromCache'])); - DocumentSnapshot document = snapshot.documents.first; + DocumentSnapshotPlatform document = snapshot.documents.first; expect(document.documentID, equals('0')); expect(document.reference.path, equals('bar/0')); expect(document.data, equals(kMockDocumentSnapshotData)); @@ -1099,7 +1101,7 @@ void main() { // Cannot order by document id when paginating with documents. final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); - final DocumentSnapshot snapshot = await documentReference.get(); + final DocumentSnapshotPlatform snapshot = await documentReference.get(); expect(() { firestore .collection('foo') @@ -1110,7 +1112,7 @@ void main() { test('document pagination FieldPath assertions', () async { final DocumentReferencePlatform documentReference = firestore.document('foo/bar'); - final DocumentSnapshot snapshot = await documentReference.get(); + final DocumentSnapshotPlatform snapshot = await documentReference.get(); final QueryPlatform query = firestore.collection('foo').orderBy(FieldPath.documentId); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index 6887c1a3a362..a555cd07ca33 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -75,7 +75,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { _resetQueryDelegate(); return queryDelegate.endAtDocument(documentSnapshot); } @@ -87,7 +87,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { _resetQueryDelegate(); return queryDelegate.endBeforeDocument(documentSnapshot); } @@ -144,7 +144,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { _resetQueryDelegate(); return queryDelegate.startAfterDocument(documentSnapshot); } @@ -156,7 +156,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { } @override - QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { _resetQueryDelegate(); return queryDelegate.startAtDocument(documentSnapshot); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart index 1358d43e8359..373ae6f83261 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -41,7 +41,7 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { delegate.update(data: CodecUtility.encodeMapData(data)); @override - Future get({ + Future get({ Source source = Source.serverAndCache, }) async { return fromWebDocumentSnapshotToPlatformDocumentSnapshot( @@ -52,7 +52,7 @@ class DocumentReferenceWeb extends DocumentReferencePlatform { Future delete() => delegate.delete(); @override - Stream snapshots({ + Stream snapshots({ bool includeMetadataChanges = false, }) { Stream querySnapshots = delegate.onSnapshot; diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index 581bcb46fac4..bd677246ab0a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -66,7 +66,7 @@ class QueryWeb extends QueryPlatform { ); @override - QueryPlatform endAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -86,7 +86,7 @@ class QueryWeb extends QueryPlatform { ); @override - QueryPlatform endBeforeDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -149,7 +149,7 @@ class QueryWeb extends QueryPlatform { ); @override - QueryPlatform startAfterDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -171,7 +171,7 @@ class QueryWeb extends QueryPlatform { ); @override - QueryPlatform startAtDocument(DocumentSnapshot documentSnapshot) { + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { assert(_webQuery != null && _orderByKeys.isNotEmpty); return QueryWeb( this._firestore, @@ -281,8 +281,9 @@ class QueryWeb extends QueryPlatform { } } - SnapshotMetadata _webMetadataToMetada(web.SnapshotMetadata webMetadata) { - return SnapshotMetadata( + SnapshotMetadataPlatform _webMetadataToMetada( + web.SnapshotMetadata webMetadata) { + return SnapshotMetadataPlatform( webMetadata.hasPendingWrites, webMetadata.fromCache, ); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart index 612a6075f45f..e93e0c8ef715 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -26,7 +26,7 @@ class TransactionWeb extends TransactionPlatform { } @override - Future get( + Future get( DocumentReferencePlatform documentReference, ) async { assert(documentReference is DocumentReferenceWeb); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart index 9ded38ee588c..e723c0025375 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart @@ -7,13 +7,13 @@ import 'package:firebase/firestore.dart' as web; import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; -/// Builds [DocumentSnapshot] instance form web snapshot instance -DocumentSnapshot fromWebDocumentSnapshotToPlatformDocumentSnapshot( +/// Builds [DocumentSnapshotPlatform] instance form web snapshot instance +DocumentSnapshotPlatform fromWebDocumentSnapshotToPlatformDocumentSnapshot( web.DocumentSnapshot webSnapshot, FirestorePlatform firestore) { - return DocumentSnapshot( + return DocumentSnapshotPlatform( webSnapshot.ref.path, CodecUtility.decodeMapData(webSnapshot.data()), - SnapshotMetadata( + SnapshotMetadataPlatform( webSnapshot.metadata.hasPendingWrites, webSnapshot.metadata.fromCache, ), diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 147aee3009dd..512605c2c041 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -33,7 +33,7 @@ class MockWebDocumentReference extends Mock implements web.DocumentReference {} class MockQueryWeb extends Mock implements QueryWeb {} -class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} +class MockDocumentSnapshot extends Mock implements DocumentSnapshotPlatform {} web.Firestore mockFirestore() { final mockFirestoreWeb = MockFirestoreWeb(); From 3b301657c5228f816d640334d019827cdddc33ad Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 17:51:37 -0800 Subject: [PATCH 132/144] Transaction constructor is properly public, not visibleForTesting. dartfmt -w --- .../cloud_firestore/lib/src/document_reference.dart | 8 ++++---- .../cloud_firestore/cloud_firestore/lib/src/query.dart | 8 ++++---- .../lib/src/platform_interface/transaction.dart | 6 +----- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart index cea1c65494ca..3830f9e3696d 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/document_reference.dart @@ -63,10 +63,10 @@ class DocumentReference { /// Reads the document referenced by this [DocumentReference]. /// /// If no document exists, the read will return null. - Future get({platform.Source source = platform.Source.serverAndCache,}) async { - return DocumentSnapshot._( - await _delegate.get(source: source), - firestore); + Future get({ + platform.Source source = platform.Source.serverAndCache, + }) async { + return DocumentSnapshot._(await _delegate.get(source: source), firestore); } /// Deletes the document referred to by this [DocumentReference]. diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart index a883dd6629db..513cfce5b554 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/query.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/query.dart @@ -30,11 +30,11 @@ class Query { .map((item) => QuerySnapshot._(item, firestore)); /// Fetch the documents for this query - Future getDocuments( - {platform.Source source = platform.Source.serverAndCache,}) async { + Future getDocuments({ + platform.Source source = platform.Source.serverAndCache, + }) async { assert(source != null); - final docs = await _delegate.getDocuments( - source: source); + final docs = await _delegate.getDocuments(source: source); return QuerySnapshot._(docs, firestore); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart index f82a3c4269f6..9bd09e9bbf9c 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/transaction.dart @@ -4,8 +4,6 @@ import 'dart:async'; -import 'package:flutter/foundation.dart'; -import 'package:meta/meta.dart' show visibleForTesting; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; @@ -16,9 +14,7 @@ typedef Future TransactionHandler(TransactionPlatform transaction); /// a [TransactionPlatform] is a set of read and write operations on one or more documents. abstract class TransactionPlatform extends PlatformInterface { - // disabling lint as it's only visible for testing - // ignore: public_member_api_docs - @visibleForTesting + /// Constructor. TransactionPlatform(this.firestore) : super(token: _token); static final Object _token = Object(); From 926ba5514c83a8c5a322749ebcbc0205a7fb28eb Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Mon, 3 Feb 2020 19:18:58 -0800 Subject: [PATCH 133/144] Do not export auto_id_generator from PlatformInterface. * Web doesn't need it, it can delegate all that logic to the JS client. * It's only required for MethodChannel. Move it to method_channel/utils. --- .../lib/cloud_firestore_platform_interface.dart | 2 -- .../method_channel_collection_reference.dart | 1 + .../utils/auto_id_generator.dart | 0 .../lib/src/collection_reference_web.dart | 5 +++-- .../test/collection_reference_web_test.dart | 12 ++++++++++++ .../cloud_firestore_web/test/test_common.dart | 3 +++ 6 files changed, 19 insertions(+), 4 deletions(-) rename packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/{ => method_channel}/utils/auto_id_generator.dart (100%) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 1c48ef91fa92..7fd20ff339b8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -17,8 +17,6 @@ import 'src/platform_interface/query.dart'; import 'src/platform_interface/transaction.dart'; import 'src/platform_interface/write_batch.dart'; -export 'src/utils/auto_id_generator.dart'; - // Shared types export 'src/blob.dart'; export 'src/document_snapshot.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart index b555b561da18..8cf7dc9657a1 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_collection_reference.dart @@ -7,6 +7,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'method_channel_query.dart'; import 'method_channel_document_reference.dart'; +import 'utils/auto_id_generator.dart'; /// A CollectionReference object can be used for adding documents, getting /// document references, and querying for documents (using the methods diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/auto_id_generator.dart similarity index 100% rename from packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/utils/auto_id_generator.dart rename to packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/auto_id_generator.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index a555cd07ca33..a75131e7e2b9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -46,8 +46,9 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { DocumentReferencePlatform document([String path]) { List childPath; if (path == null) { - final String key = AutoIdGenerator.autoId(); - childPath = List.from(pathComponents)..add(key); + web.DocumentReference doc = + webFirestore.collection(pathComponents.join('/')).doc(); + childPath = doc.path.split('/'); } else { childPath = List.from(pathComponents)..addAll(path.split(('/'))); } diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart index 7399a2fd1ebc..6b2c8c19973a 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -15,6 +15,8 @@ import 'test_common.dart'; void main() { group("$CollectionReferenceWeb()", () { final mockDocumentReference = MockWebDocumentReference(); + final mockCollectionReference = MockWebCollectionReference(); + final anotherMockDocumentReference = MockWebDocumentReference(); CollectionReferenceWeb collectionReference; setUp(() { final mockFirestoreWeb = mockFirestore(); @@ -22,6 +24,16 @@ void main() { js.context['firebase']['firestore'](""), [kCollectionId]); collectionReference.queryDelegate = MockQueryWeb(); when(mockFirestoreWeb.doc(any)).thenReturn(mockDocumentReference); + + // Used for document creation... + when(mockFirestoreWeb.collection(any)) + .thenReturn(mockCollectionReference); + when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); + when(mockCollectionReference.doc(null)) + .thenReturn(anotherMockDocumentReference); + + when(anotherMockDocumentReference.path).thenReturn("test/asdf"); + when(collectionReference.queryDelegate.resetQueryDelegate()) .thenReturn(collectionReference.queryDelegate); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 512605c2c041..28ebd3587da7 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -31,6 +31,9 @@ class MockFirestore extends Mock implements FirestoreWeb {} class MockWebDocumentReference extends Mock implements web.DocumentReference {} +class MockWebCollectionReference extends Mock + implements web.CollectionReference {} + class MockQueryWeb extends Mock implements QueryWeb {} class MockDocumentSnapshot extends Mock implements DocumentSnapshotPlatform {} From 4cb361cb5a0cc17d0e4239fc35e103cc98141bf1 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 4 Feb 2020 14:13:20 -0800 Subject: [PATCH 134/144] Remove as much logic as possible from FieldValue instances. This change exposes the FieldValuePlatform abstract class to plugin users, so they can have a way of typing the result of calling the FieldValue.whatever() methods, without having to keep an internal 'instance' as part of the exposed interface. --- .../cloud_firestore/lib/cloud_firestore.dart | 11 +++-- .../cloud_firestore/lib/src/field_value.dart | 41 +++++++--------- .../cloud_firestore_platform_interface.dart | 1 - .../method_channel_document_reference.dart | 14 ++++-- .../method_channel_field_value.dart | 35 ++++++++++++++ .../method_channel_field_value_factory.dart | 14 +++--- .../method_channel_transaction.dart | 5 +- .../method_channel_write_batch.dart | 5 +- .../utils/firestore_message_codec.dart | 3 +- .../lib/src/method_channel/utils/maps.dart | 20 -------- .../src/platform_interface/field_value.dart | 48 ------------------- .../field_value_factory.dart | 41 +++++++--------- .../test/field_value_test.dart | 24 ---------- .../method_channel_cloud_firestore_test.dart | 13 +++-- .../method_channel_document_reference.dart | 11 ++--- ...thod_channel_field_value_factory_test.dart | 14 +++--- .../test/transaction_test.dart | 12 ++--- .../lib/src/field_value_factory_web.dart | 35 ++++---------- .../lib/src/field_value_web.dart | 13 +---- .../lib/src/utils/codec_utility.dart | 4 +- .../test/codec_utility_test.dart | 2 - .../test/field_value_factory_web_test.dart | 41 ++++++++-------- 22 files changed, 159 insertions(+), 248 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 298ab4efaf25..4739c44931c5 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -7,14 +7,19 @@ library cloud_firestore; import 'dart:async'; import 'dart:ui' show hashList; -import 'package:flutter/foundation.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' as platform; import 'package:firebase_core/firebase_core.dart'; -import 'package:meta/meta.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' - show FieldPath, Blob, GeoPoint, Timestamp, Source, DocumentChangeType; + show + FieldPath, + FieldValuePlatform, + Blob, + GeoPoint, + Timestamp, + Source, + DocumentChangeType; part 'src/collection_reference.dart'; part 'src/document_change.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index f4451af424ac..6912765cde92 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -6,21 +6,13 @@ part of cloud_firestore; /// Sentinel values that can be used when writing document fields with set() or /// update(). -class FieldValue extends platform.FieldValuePlatform { - platform.FieldValuePlatform _delegate; - - FieldValue._(this._delegate) : super(_delegate.type, _delegate.value) { - platform.FieldValuePlatform.verifyExtends(_delegate); - } - - @override - platform.FieldValuePlatform get instance => _delegate; - - @visibleForTesting - platform.FieldValueType get type => _delegate.type; - - @visibleForTesting - dynamic get value => _delegate.value; +/// +/// This class serves as a static factory for FieldValuePlatform instances, but also +/// as a Facade for the Fieldvalue type, so plugin users don't need to worry about +/// the actual internal implementation of their Fieldvalues, after they're created. +class FieldValue { + static final platform.FieldValueFactoryPlatform _delegate = + platform.FieldValueFactoryPlatform.instance; /// Returns a special value that tells the server to union the given elements /// with any array value that already exists on the server. @@ -29,8 +21,8 @@ class FieldValue extends platform.FieldValuePlatform { /// added to the end. If the field being modified is not already an array it /// will be overwritten with an array containing exactly the specified /// elements. - static FieldValue arrayUnion(List elements) => FieldValue._( - platform.FieldValueFactoryPlatform.instance.arrayUnion(elements)); + static platform.FieldValuePlatform arrayUnion(List elements) => + _delegate.arrayUnion(elements); /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -38,20 +30,19 @@ class FieldValue extends platform.FieldValuePlatform { /// All instances of each element specified will be removed from the array. /// If the field being modified is not already an array it will be overwritten /// with an empty array. - static FieldValue arrayRemove(List elements) => FieldValue._( - platform.FieldValueFactoryPlatform.instance.arrayRemove(elements)); + static platform.FieldValuePlatform arrayRemove(List elements) => + _delegate.arrayRemove(elements); /// Returns a sentinel for use with update() to mark a field for deletion. - static FieldValue delete() => - FieldValue._(platform.FieldValueFactoryPlatform.instance.delete()); + static platform.FieldValuePlatform delete() => _delegate.delete(); /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. - static FieldValue serverTimestamp() => FieldValue._( - platform.FieldValueFactoryPlatform.instance.serverTimestamp()); + static platform.FieldValuePlatform serverTimestamp() => + _delegate.serverTimestamp(); /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - static FieldValue increment(num value) => FieldValue._( - platform.FieldValueFactoryPlatform.instance.increment(value)); + static platform.FieldValuePlatform increment(num value) => + _delegate.increment(value); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart index 7fd20ff339b8..4ec5ff762223 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/cloud_firestore_platform_interface.dart @@ -30,7 +30,6 @@ export 'src/timestamp.dart'; export 'src/platform_interface/collection_reference.dart'; export 'src/platform_interface/document_change.dart'; export 'src/platform_interface/document_reference.dart'; -export 'src/platform_interface/field_value.dart'; export 'src/platform_interface/field_value_factory.dart'; export 'src/platform_interface/query.dart'; export 'src/platform_interface/query_snapshot.dart'; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart index c8aac67397af..fc4f552f45d4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_document_reference.dart @@ -21,13 +21,16 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { super(firestore, pathComponents); @override - Future setData(Map data, {bool merge = false}) { + Future setData( + Map data, { + bool merge = false, + }) { return MethodChannelFirestore.channel.invokeMethod( 'DocumentReference#setData', { 'app': firestore.app.name, 'path': path, - 'data': unwrapFieldValueInterfaceToPlatformType(data), + 'data': data, 'options': {'merge': merge}, }, ); @@ -40,14 +43,15 @@ class MethodChannelDocumentReference extends DocumentReferencePlatform { { 'app': firestore.app.name, 'path': path, - 'data': unwrapFieldValueInterfaceToPlatformType(data), + 'data': data, }, ); } @override - Future get( - {Source source = Source.serverAndCache}) async { + Future get({ + Source source = Source.serverAndCache, + }) async { final Map data = await MethodChannelFirestore.channel.invokeMapMethod( 'DocumentReference#get', diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value.dart new file mode 100644 index 000000000000..0a598dfbefb0 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value.dart @@ -0,0 +1,35 @@ +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; + +/// Sentinel values that can be used when writing document fields with set() or +/// update(). +enum FieldValueType { + /// adds elements to an array but only elements not already present + arrayUnion, + + /// removes all instances of each given element + arrayRemove, + + /// deletes field + delete, + + /// sets field value to server timestamp + serverTimestamp, + + /// increment or decrement a numeric field value using a double value + incrementDouble, + + /// increment or decrement a numeric field value using an integer value + incrementInteger, +} + +/// MethodChannel implementation of a [FieldValuePlatform]. +class MethodChannelFieldValue extends FieldValuePlatform { + /// Constructor. + MethodChannelFieldValue(this.type, this.value) : super(); + + /// The type of FieldValue. + final FieldValueType type; + + /// The value associated with the FieldValueType above. + final dynamic value; +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart index 961ba949fc7f..5448d0375b41 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_field_value_factory.dart @@ -6,20 +6,22 @@ import 'package:flutter/services.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'method_channel_field_value.dart'; + /// An implementation of [FieldValueFactoryPlatform] that is suitable to be used /// on mobile where communication relies on [MethodChannel] class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { @override FieldValuePlatform arrayRemove(List elements) => - FieldValuePlatform(FieldValueType.arrayRemove, elements); + MethodChannelFieldValue(FieldValueType.arrayRemove, elements); @override FieldValuePlatform arrayUnion(List elements) => - FieldValuePlatform(FieldValueType.arrayUnion, elements); + MethodChannelFieldValue(FieldValueType.arrayUnion, elements); @override FieldValuePlatform delete() => - FieldValuePlatform(FieldValueType.delete, null); + MethodChannelFieldValue(FieldValueType.delete, null); @override FieldValuePlatform increment(num value) { @@ -27,14 +29,14 @@ class MethodChannelFieldValueFactory extends FieldValueFactoryPlatform { // attempt to extend or implement `num`. assert(value is int || value is double); if (value is double) { - return FieldValuePlatform(FieldValueType.incrementDouble, value); + return MethodChannelFieldValue(FieldValueType.incrementDouble, value); } else if (value is int) { - return FieldValuePlatform(FieldValueType.incrementInteger, value); + return MethodChannelFieldValue(FieldValueType.incrementInteger, value); } return null; } @override FieldValuePlatform serverTimestamp() => - FieldValuePlatform(FieldValueType.serverTimestamp, null); + MethodChannelFieldValue(FieldValueType.serverTimestamp, null); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart index 8e72971b2541..dce12a4ecc33 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_transaction.dart @@ -9,7 +9,6 @@ import 'package:flutter/services.dart'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'method_channel_firestore.dart'; -import 'utils/maps.dart'; /// An implementation of [TransactionPlatform] which uses [MethodChannel] to /// communication with native plugin @@ -67,7 +66,7 @@ class MethodChannelTransaction extends TransactionPlatform { 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, - 'data': unwrapFieldValueInterfaceToPlatformType(data), + 'data': data, }); } @@ -81,7 +80,7 @@ class MethodChannelTransaction extends TransactionPlatform { 'app': firestore.app.name, 'transactionId': _transactionId, 'path': documentReference.path, - 'data': unwrapFieldValueInterfaceToPlatformType(data), + 'data': data, }); } } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart index ecec2fd27785..747e68004fb4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_write_batch.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'method_channel_firestore.dart'; -import 'utils/maps.dart'; /// A [MethodChannelWriteBatch] is a series of write operations to be performed as one unit. /// @@ -71,7 +70,7 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { 'app': _firestore.app.name, 'handle': handle, 'path': document.path, - 'data': unwrapFieldValueInterfaceToPlatformType(data), + 'data': data, 'options': {'merge': merge}, }, ), @@ -94,7 +93,7 @@ class MethodChannelWriteBatch extends WriteBatchPlatform { 'app': _firestore.app.name, 'handle': handle, 'path': document.path, - 'data': unwrapFieldValueInterfaceToPlatformType(data) + 'data': data }, ), ); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index a7e14e6e4b8a..64ea4237284f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:cloud_firestore_platform_interface/src/internal/field_path_type.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; /// The codec utilized to encode data back and forth between /// the Dart application and the native platform. @@ -68,7 +69,7 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putUint8(_kBlob); writeSize(buffer, value.bytes.length); buffer.putUint8List(value.bytes); - } else if (value is FieldValuePlatform) { + } else if (value is MethodChannelFieldValue) { final int code = _kFieldValueCodes[value.type]; assert(code != null); buffer.putUint8(code); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart index bcd8dcb554d7..038c74633892 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/maps.dart @@ -2,26 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:cloud_firestore_platform_interface/src/platform_interface/field_value.dart'; - /// Casts a Map to Map Map asStringKeyedMap(Map map) => map?.cast(); - -/// Replaces items with type [FieldValueInterface] with implementation type -/// such as [FieldValuePlatform] -Map unwrapFieldValueInterfaceToPlatformType( - Map data) { - if (data == null) { - return null; - } - Map output = Map.from(data); - output.updateAll((key, value) { - if (value is FieldValueInterface && value.instance is FieldValuePlatform) { - return value.instance; - } else { - return value; - } - }); - return output; -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart deleted file mode 100644 index b18ca2c75558..000000000000 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; - -/// A class to define an interface that's required -/// for building platform-specific implementation -abstract class FieldValueInterface { - /// Implementation instance - FieldValueInterface get instance; - - /// type of the FieldValue - FieldValueType get type; - - /// value of the FieldValue - dynamic get value; -} - -/// Platform Interface of a FieldValue; implementation for [FieldValueInterface] -class FieldValuePlatform extends PlatformInterface - implements FieldValueInterface { - static final Object _token = Object(); - - /// Throws an [AssertionError] if [instance] does not extend - /// [FieldValuePlatform]. - /// - /// This is used by the app-facing [FieldValue] to ensure that - /// the object in which it's going to delegate calls has been - /// constructed properly. - static verifyExtends(FieldValuePlatform instance) { - PlatformInterface.verifyToken(instance, _token); - } - - /// Constructor - FieldValuePlatform(this.type, this.value) : super(token: _token); - - @override - FieldValuePlatform get instance => this; - - @override - final FieldValueType type; - - @override - final dynamic value; -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index 54723dbf154e..e9e3159dc06f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -5,29 +5,6 @@ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; - -/// Sentinel values that can be used when writing document fields with set() or -/// update(). -enum FieldValueType { - /// adds elements to an array but only elements not already present - arrayUnion, - - /// removes all instances of each given element - arrayRemove, - - /// deletes field - delete, - - /// sets field value to server timestamp - serverTimestamp, - - /// increment or decrement a numeric field value using a double value - incrementDouble, - - /// increment or decrement a numeric field value using an integer value - incrementInteger, -} /// An interface for a factory that is used to build [FieldValuePlatform] according to /// Platform (web or mobile) @@ -97,3 +74,21 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { throw UnimplementedError("increment() is not implemented"); } } + +/// This is a cross-platform representation of a FieldValue. +/// +/// Each concrete platform implementation will extend this class, +/// and add any relevant methods or values to it, so it works as +/// expected for the target platform. +/// +/// This is exposed to plugin users, so they can correctly type the +/// results of calling FieldValueFactory instances, but you should +/// never "peek" inside subclasses of this. +/// +/// Just treat it as a "black box". +abstract class FieldValuePlatform extends PlatformInterface { + static final Object _token = Object(); + + /// Constructor + FieldValuePlatform() : super(token: _token); +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart deleted file mode 100644 index 67136d9832f1..000000000000 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/field_value_test.dart +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -import 'package:cloud_firestore_platform_interface/src/method_channel/utils/maps.dart'; - -class MockFieldValue extends Mock implements FieldValuePlatform {} - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - group("$unwrapFieldValueInterfaceToPlatformType()", () { - test("unwrapFieldValueInterfaces", () { - expect(unwrapFieldValueInterfaceToPlatformType(null), isNull); - - final mockFieldValue = MockFieldValue(); - unwrapFieldValueInterfaceToPlatformType({"item": mockFieldValue}); - verify(mockFieldValue.instance); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 6a9bc33772c6..3eeeb6b66b00 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -11,6 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_transaction.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart'; void main() { @@ -1403,8 +1404,8 @@ bool _deepEquals(dynamic valueA, dynamic valueB) { if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; - if (valueA is FieldValuePlatform) { - return valueB is FieldValuePlatform && + if (valueA is MethodChannelFieldValue) { + return valueB is MethodChannelFieldValue && _deepEqualsFieldValue(valueA, valueB); } if (valueA is FieldPath) { @@ -1443,7 +1444,9 @@ bool _deepEqualsList(List valueA, List valueB) { } bool _deepEqualsMap( - Map valueA, Map valueB) { + Map valueA, + Map valueB, +) { if (valueA.length != valueB.length) return false; for (final dynamic key in valueA.keys) { if (!valueB.containsKey(key) || !_deepEquals(valueA[key], valueB[key])) { @@ -1454,7 +1457,9 @@ bool _deepEqualsMap( } bool _deepEqualsFieldValue( - FieldValuePlatform valueA, FieldValuePlatform valueB) { + MethodChannelFieldValue valueA, + MethodChannelFieldValue valueB, +) { if (valueA.type != valueB.type) return false; if (valueA.value == null) return valueB.value == null; if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 265a24455c2d..1f90dac29cb4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -7,23 +7,22 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; import 'test_common.dart'; -class MockFiledValue extends Mock implements FieldValuePlatform {} - void main() { TestWidgetsFlutterBinding.ensureInitialized(); group("$MethodChannelDocumentReference()", () { MethodChannelDocumentReference _documentReference; - final mockFieldValue = MockFiledValue(); + MethodChannelFieldValue mockFieldValue = + MethodChannelFieldValueFactory().increment(2.0); setUp(() { _documentReference = MethodChannelDocumentReference( FirestorePlatform.instance, [kCollectionId, kDocumentId]); reset(mockFieldValue); - when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); - when(mockFieldValue.value).thenReturn(2.0); }); test("setData", () async { @@ -31,7 +30,6 @@ void main() { _assertSetDataMethodCalled(_documentReference, true, null); _assertSetDataMethodCalled(_documentReference, false, null); _assertSetDataMethodCalled(_documentReference, false, mockFieldValue); - verify(mockFieldValue.instance); }); test("updateData", () async { @@ -47,7 +45,6 @@ void main() { } }); await _documentReference.updateData(data); - verify(mockFieldValue.instance); expect(isMethodCalled, isTrue, reason: "DocumentReference.updateData was not called"); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart index e3c85736010c..9edeb8601ceb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_field_value_factory_test.dart @@ -2,35 +2,35 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; void main() { group("$MethodChannelFieldValueFactory()", () { final MethodChannelFieldValueFactory factory = MethodChannelFieldValueFactory(); test("arrayRemove", () { - final actual = factory.arrayRemove([1]); + final MethodChannelFieldValue actual = factory.arrayRemove([1]); expect(actual.type, equals(FieldValueType.arrayRemove)); }); test("arrayUnion", () { - final actual = factory.arrayUnion([1]); + final MethodChannelFieldValue actual = factory.arrayUnion([1]); expect(actual.type, equals(FieldValueType.arrayUnion)); }); test("delete", () { - final actual = factory.delete(); + final MethodChannelFieldValue actual = factory.delete(); expect(actual.type, equals(FieldValueType.delete)); }); test("increment", () { - final actualInt = factory.increment(1); + final MethodChannelFieldValue actualInt = factory.increment(1); expect(actualInt.type, equals(FieldValueType.incrementInteger)); - final actualDouble = factory.increment(1.0); + final MethodChannelFieldValue actualDouble = factory.increment(1.0); expect(actualDouble.type, equals(FieldValueType.incrementDouble)); }); test("serverTimestamp", () { - final actual = factory.serverTimestamp(); + final MethodChannelFieldValue actual = factory.serverTimestamp(); expect(actual.type, equals(FieldValueType.serverTimestamp)); }); }); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 8663118383eb..0adea06ee2b9 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -7,18 +7,19 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_transaction.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; +import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; import 'test_common.dart'; class MockDocumentReference extends Mock implements DocumentReferencePlatform {} -class MockFiledValue extends Mock implements FieldValuePlatform {} - const _kTransactionId = 1022; void main() { TestWidgetsFlutterBinding.ensureInitialized(); - final mockFieldValue = MockFiledValue(); + final MethodChannelFieldValue mockFieldValue = + MethodChannelFieldValueFactory().increment(2.0); group("$MethodChannelTransaction()", () { TransactionPlatform transaction; @@ -27,9 +28,6 @@ void main() { setUp(() { transaction = MethodChannelTransaction( _kTransactionId, FirestorePlatform.instance.app.name); - reset(mockFieldValue); - when(mockFieldValue.type).thenReturn(FieldValueType.incrementDouble); - when(mockFieldValue.value).thenReturn(2.0); }); test("get", () async { @@ -71,7 +69,6 @@ void main() { } }); await transaction.update(mockDocumentReference, data); - verify(mockFieldValue.instance); expect(isMethodCalled, isTrue, reason: "Transaction#update was not called"); }); @@ -90,7 +87,6 @@ void main() { } }); await transaction.set(mockDocumentReference, data); - verify(mockFieldValue.instance); expect(isMethodCalled, isTrue, reason: "Transaction#set was not called"); }); }); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart index e0957203c734..cfae0922dfa1 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart @@ -12,38 +12,21 @@ import 'package:cloud_firestore_web/src/field_value_web.dart'; /// instance that is [jsify] friendly class FieldValueFactoryWeb extends FieldValueFactoryPlatform { @override - FieldValuePlatform arrayRemove(List elements) { - final delegate = web.FieldValue.arrayRemove(elements); - return FieldValueWeb(delegate, FieldValueType.arrayRemove, elements); - } + FieldValuePlatform arrayRemove(List elements) => + FieldValueWeb(web.FieldValue.arrayRemove(elements)); @override - FieldValuePlatform arrayUnion(List elements) { - final delegate = web.FieldValue.arrayUnion(elements); - return FieldValueWeb(delegate, FieldValueType.arrayUnion, elements); - } + FieldValuePlatform arrayUnion(List elements) => + FieldValueWeb(web.FieldValue.arrayUnion(elements)); @override - FieldValuePlatform delete() { - final delegate = web.FieldValue.delete(); - return FieldValueWeb(delegate, FieldValueType.delete, null); - } + FieldValuePlatform delete() => FieldValueWeb(web.FieldValue.delete()); @override - FieldValuePlatform increment(num value) { - assert(value is double || value is int, "value can only be double or int"); - final delegate = web.FieldValue.increment(value); - return FieldValueWeb( - delegate, - value is int - ? FieldValueType.incrementInteger - : FieldValueType.incrementDouble, - value); - } + FieldValuePlatform increment(num value) => + FieldValueWeb(web.FieldValue.increment(value)); @override - FieldValuePlatform serverTimestamp() { - final delegate = web.FieldValue.serverTimestamp(); - return FieldValueWeb(delegate, FieldValueType.serverTimestamp, null); - } + FieldValuePlatform serverTimestamp() => + FieldValueWeb(web.FieldValue.serverTimestamp()); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart index c3003c15e255..c3e7e5c38881 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -9,17 +9,8 @@ import 'package:firebase/firestore.dart' as web; /// firestore web plugin class FieldValueWeb extends FieldValuePlatform { /// The js-interop delegate for this [FieldValuePlatform] - web.FieldValue delegate; + web.FieldValue data; /// Constructor. - FieldValueWeb(this.delegate, this.type, this.value) : super(type, value); - - @override - final FieldValueType type; - - @override - final dynamic value; - - @override - FieldValuePlatform get instance => this; + FieldValueWeb(this.data) : super(); } diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index 87e9cd678bf9..bc4f9f0af8ab 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -31,8 +31,8 @@ class CodecUtility { /// Encodes a value from its proper type to a serialized version. static dynamic valueEncode(dynamic value) { - if (value is FieldValuePlatform && value.instance is FieldValueWeb) { - return (value.instance as FieldValueWeb).delegate; + if (value is FieldValueWeb) { + return value.data; } else if (value is Timestamp) { return value.toDate(); } else if (value is GeoPoint) { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index c2a8c2d37dd8..4fd4a9eeac84 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -44,7 +44,6 @@ void main() { //FieldValuePlatform final mockFieldValue = MockFieldValue(); CodecUtility.encodeMapData({'test': mockFieldValue}); - verify(mockFieldValue.instance); final timeStamp = Timestamp.now(); final result = CodecUtility.encodeMapData({'test': timeStamp}); @@ -87,7 +86,6 @@ void main() { //FieldValuePlatform final mockFieldValue = MockFieldValue(); CodecUtility.encodeArrayData([mockFieldValue]); - verify(mockFieldValue.instance); final timeStamp = Timestamp.now(); final result = CodecUtility.encodeArrayData([timeStamp]); diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart index 3efe86c06b1f..566c2ab39938 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn("chrome") -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web show FieldValue; import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; import 'package:cloud_firestore_web/src/field_value_web.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -13,37 +13,40 @@ void main() { final factory = FieldValueFactoryWeb(); test("arrayRemove", () { - final actual = factory.arrayRemove([]); - expect(actual, isInstanceOf()); - expect(actual.type, equals(FieldValueType.arrayRemove)); + final FieldValueWeb actual = factory.arrayRemove([]); + expect(actual.data, isInstanceOf()); }); test("arrayUnion", () { - final actual = factory.arrayUnion([]); - expect(actual, isInstanceOf()); - expect(actual.type, equals(FieldValueType.arrayUnion)); + final FieldValueWeb actual = factory.arrayUnion([]); + expect(actual.data, isInstanceOf()); }); test("delete", () { - final actual = factory.delete(); - expect(actual, isInstanceOf()); - expect(actual.type, equals(FieldValueType.delete)); + final FieldValueWeb actual = factory.delete(); + expect(actual.data, isInstanceOf()); }); test("increment", () { - final actualInt = factory.increment(1); - expect(actualInt, isInstanceOf()); - expect(actualInt.type, equals(FieldValueType.incrementInteger)); + final FieldValueWeb actualInt = factory.increment(1); + expect(actualInt.data, isInstanceOf()); - final actualDouble = factory.increment(1.25); - expect(actualDouble, isInstanceOf()); - expect(actualDouble.type, equals(FieldValueType.incrementDouble)); + final FieldValueWeb actualDouble = factory.increment(1.25); + expect(actualDouble.data, isInstanceOf()); + }); + + test( + "increment throws when attempting to increment something that is not a number", + () { + expect(() { + dynamic malformed = "nope"; + factory.increment(malformed); + }, throwsA(isA())); }); test("serverTimestamp", () { - final actual = factory.serverTimestamp(); - expect(actual, isInstanceOf()); - expect(actual.type, equals(FieldValueType.serverTimestamp)); + final FieldValueWeb actual = factory.serverTimestamp(); + expect(actual.data, isInstanceOf()); }); }); } From 7c92e7c808f6d56b77d0bf824187950dff0a8d29 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 4 Feb 2020 18:46:30 -0800 Subject: [PATCH 135/144] FieldValue now internally stores the platform-dependent value. Refactor tests and code around the new API. --- .../cloud_firestore/lib/cloud_firestore.dart | 9 +-- .../cloud_firestore/lib/src/field_value.dart | 26 ++++--- .../method_channel_firestore.dart | 2 +- .../utils/firestore_message_codec.dart | 23 ++---- .../field_value_factory.dart | 21 +++++- .../test/document_reference_test.dart | 5 +- .../method_channel_cloud_firestore_test.dart | 73 +++++++++++++++---- ...hod_channel_collection_reference_test.dart | 4 +- .../method_channel_document_reference.dart | 2 +- .../test/query_test.dart | 5 +- .../test/test_common.dart | 11 +++ .../test/test_firestore_message_codec.dart | 54 ++++++++++++++ .../test/transaction_test.dart | 10 +-- .../lib/src/utils/codec_utility.dart | 5 +- .../test/codec_utility_test.dart | 10 +-- 15 files changed, 191 insertions(+), 69 deletions(-) create mode 100644 packages/cloud_firestore/cloud_firestore_platform_interface/test/test_firestore_message_codec.dart diff --git a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart index 4739c44931c5..87683c7465ef 100755 --- a/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/cloud_firestore.dart @@ -12,14 +12,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_inte import 'package:firebase_core/firebase_core.dart'; export 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart' - show - FieldPath, - FieldValuePlatform, - Blob, - GeoPoint, - Timestamp, - Source, - DocumentChangeType; + show FieldPath, Blob, GeoPoint, Timestamp, Source, DocumentChangeType; part 'src/collection_reference.dart'; part 'src/document_change.dart'; diff --git a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart index 6912765cde92..3e9d9acca713 100644 --- a/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart +++ b/packages/cloud_firestore/cloud_firestore/lib/src/field_value.dart @@ -10,10 +10,14 @@ part of cloud_firestore; /// This class serves as a static factory for FieldValuePlatform instances, but also /// as a Facade for the Fieldvalue type, so plugin users don't need to worry about /// the actual internal implementation of their Fieldvalues, after they're created. -class FieldValue { - static final platform.FieldValueFactoryPlatform _delegate = +class FieldValue extends platform.FieldValuePlatform { + static final platform.FieldValueFactoryPlatform _factory = platform.FieldValueFactoryPlatform.instance; + FieldValue._(platform.FieldValuePlatform delegate) : super(delegate) { + platform.FieldValuePlatform.verifyExtends(delegate); + } + /// Returns a special value that tells the server to union the given elements /// with any array value that already exists on the server. /// @@ -21,8 +25,8 @@ class FieldValue { /// added to the end. If the field being modified is not already an array it /// will be overwritten with an array containing exactly the specified /// elements. - static platform.FieldValuePlatform arrayUnion(List elements) => - _delegate.arrayUnion(elements); + static FieldValue arrayUnion(List elements) => + FieldValue._(_factory.arrayUnion(elements)); /// Returns a special value that tells the server to remove the given /// elements from any array value that already exists on the server. @@ -30,19 +34,19 @@ class FieldValue { /// All instances of each element specified will be removed from the array. /// If the field being modified is not already an array it will be overwritten /// with an empty array. - static platform.FieldValuePlatform arrayRemove(List elements) => - _delegate.arrayRemove(elements); + static FieldValue arrayRemove(List elements) => + FieldValue._(_factory.arrayRemove(elements)); /// Returns a sentinel for use with update() to mark a field for deletion. - static platform.FieldValuePlatform delete() => _delegate.delete(); + static FieldValue delete() => FieldValue._(_factory.delete()); /// Returns a sentinel for use with set() or update() to include a /// server-generated timestamp in the written data. - static platform.FieldValuePlatform serverTimestamp() => - _delegate.serverTimestamp(); + static FieldValue serverTimestamp() => + FieldValue._(_factory.serverTimestamp()); /// Returns a special value for use with set() or update() that tells the /// server to increment the field’s current value by the given value. - static platform.FieldValuePlatform increment(num value) => - _delegate.increment(value); + static FieldValue increment(num value) => + FieldValue._(_factory.increment(value)); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart index c86075e90ade..d930a49c52f8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/method_channel_firestore.dart @@ -59,7 +59,7 @@ class MethodChannelFirestore extends FirestorePlatform { static bool _initialized = false; /// The [MethodChannel] used to communicate with the native plugin - static const MethodChannel channel = MethodChannel( + static MethodChannel channel = MethodChannel( 'plugins.flutter.io/cloud_firestore', StandardMethodCodec(FirestoreMessageCodec()), ); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart index 64ea4237284f..38fe441380fd 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/firestore_message_codec.dart @@ -69,11 +69,12 @@ class FirestoreMessageCodec extends StandardMessageCodec { buffer.putUint8(_kBlob); writeSize(buffer, value.bytes.length); buffer.putUint8List(value.bytes); - } else if (value is MethodChannelFieldValue) { - final int code = _kFieldValueCodes[value.type]; + } else if (value is FieldValuePlatform) { + MethodChannelFieldValue delegate = FieldValuePlatform.getDelegate(value); + final int code = _kFieldValueCodes[delegate.type]; assert(code != null); buffer.putUint8(code); - if (value.value != null) writeValue(buffer, value.value); + if (delegate.value != null) writeValue(buffer, delegate.value); } else if (value is FieldPath) { final int code = _kFieldPathCodes[value.type]; assert(code != null); @@ -107,24 +108,16 @@ class FirestoreMessageCodec extends StandardMessageCodec { final int length = readSize(buffer); final List bytes = buffer.getUint8List(length); return Blob(bytes); + case _kDocumentId: + return FieldPath.documentId; case _kArrayUnion: - final List value = readValue(buffer); - return FieldValueFactoryPlatform.instance.arrayUnion(value); case _kArrayRemove: - final List value = readValue(buffer); - return FieldValueFactoryPlatform.instance.arrayRemove(value); case _kDelete: - return FieldValueFactoryPlatform.instance.delete(); case _kServerTimestamp: - return FieldValueFactoryPlatform.instance.serverTimestamp(); case _kIncrementDouble: - final double value = readValue(buffer); - return FieldValueFactoryPlatform.instance.increment(value); case _kIncrementInteger: - final int value = readValue(buffer); - return FieldValueFactoryPlatform.instance.increment(value); - case _kDocumentId: - return FieldPath.documentId; + // These cases are only needed on tests, and therefore handled + // by [TestFirestoreMessageCodec], a subclass of this codec. default: return super.readValueOfType(type, buffer); } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart index e9e3159dc06f..78ba8f1d18ab 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/field_value_factory.dart @@ -86,9 +86,26 @@ abstract class FieldValueFactoryPlatform extends PlatformInterface { /// never "peek" inside subclasses of this. /// /// Just treat it as a "black box". -abstract class FieldValuePlatform extends PlatformInterface { +class FieldValuePlatform extends PlatformInterface { static final Object _token = Object(); /// Constructor - FieldValuePlatform() : super(token: _token); + FieldValuePlatform([this._delegate]) : super(token: _token); + + final FieldValuePlatform _delegate; + + /// Throws an [AssertionError] if [instance] does not extend + /// [FieldValuePlatform]. + /// + /// This is used by the app-facing [FieldValue] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static verifyExtends(FieldValuePlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + + /// Used by platform implementers to obtain a value suitable for being passed + /// through to the underlying implementation. + static dynamic getDelegate(FieldValuePlatform fieldValue) => + fieldValue._delegate; } diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart index 155d03cbbaf2..92cccd9fcfdb 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/document_reference_test.dart @@ -5,6 +5,8 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'test_common.dart'; + const _kCollectionId = "test"; const _kDocumentId = "document"; @@ -14,7 +16,8 @@ class TestDocumentReference extends DocumentReferencePlatform { } void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + initializeMethodChannel(); + group("$DocumentReferencePlatform()", () { test("Parent", () { final document = TestDocumentReference._(); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart index 3eeeb6b66b00..202d9ef1dff0 100755 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_cloud_firestore_test.dart @@ -14,10 +14,13 @@ import 'package:cloud_firestore_platform_interface/src/method_channel/method_cha import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart'; +import 'test_common.dart'; +import 'test_firestore_message_codec.dart'; + void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + initializeMethodChannel(); - group('$MethodChannelFirestore()', () { + group('MethodChannelFirestore()', () { int mockHandleId = 0; FirebaseApp app; MethodChannelFirestore firestore; @@ -1159,18 +1162,50 @@ void main() { }); test('encode and decode FieldValue', () { + const MessageCodec decoder = TestFirestoreMessageCodec(); + _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.arrayUnion([123])); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.arrayUnion([123]), + ), + decodingCodec: decoder, + ); _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.arrayRemove([123])); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.arrayRemove([123]), + ), + decodingCodec: decoder, + ); _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.delete()); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.delete(), + ), + decodingCodec: decoder, + ); _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.serverTimestamp()); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.serverTimestamp(), + ), + decodingCodec: decoder, + ); _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.increment(1.0)); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.increment(1.0), + ), + decodingCodec: decoder, + ); _checkEncodeDecode( - codec, FieldValueFactoryPlatform.instance.increment(1)); + codec, + FieldValuePlatform( + FieldValueFactoryPlatform.instance.increment(1), + ), + decodingCodec: decoder, + ); }); test('encode and decode FieldPath', () { @@ -1381,9 +1416,15 @@ void main() { }); } -void _checkEncodeDecode(MessageCodec codec, T message) { +void _checkEncodeDecode( + MessageCodec codec, + T message, { + MessageCodec decodingCodec, +}) { + MessageCodec decoder = decodingCodec ?? codec; + final ByteData encoded = codec.encodeMessage(message); - final T decoded = codec.decodeMessage(encoded); + final T decoded = decoder.decodeMessage(encoded); if (message == null) { expect(encoded, isNull); expect(decoded, isNull); @@ -1404,8 +1445,8 @@ bool _deepEquals(dynamic valueA, dynamic valueB) { if (valueA is List) return valueB is List && _deepEqualsList(valueA, valueB); if (valueA is Map) return valueB is Map && _deepEqualsMap(valueA, valueB); if (valueA is double && valueA.isNaN) return valueB is double && valueB.isNaN; - if (valueA is MethodChannelFieldValue) { - return valueB is MethodChannelFieldValue && + if (valueA is FieldValuePlatform) { + return valueB is FieldValuePlatform && _deepEqualsFieldValue(valueA, valueB); } if (valueA is FieldPath) { @@ -1456,10 +1497,10 @@ bool _deepEqualsMap( return true; } -bool _deepEqualsFieldValue( - MethodChannelFieldValue valueA, - MethodChannelFieldValue valueB, -) { +bool _deepEqualsFieldValue(FieldValuePlatform a, FieldValuePlatform b) { + MethodChannelFieldValue valueA = FieldValuePlatform.getDelegate(a); + MethodChannelFieldValue valueB = FieldValuePlatform.getDelegate(b); + if (valueA.type != valueB.type) return false; if (valueA.value == null) return valueB.value == null; if (valueA.value is List) return _deepEqualsList(valueA.value, valueB.value); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart index 1aaa55581197..68736b5ecde4 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_collection_reference_test.dart @@ -9,11 +9,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_collection_reference.dart'; +import 'test_common.dart'; + const _kCollectionId = "test"; const _kDocumentId = "document"; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + initializeMethodChannel(); group("$MethodChannelCollectionReference", () { MethodChannelCollectionReference _testCollection; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart index 1f90dac29cb4..dd7cd8db8e60 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/method_channel_document_reference.dart @@ -13,7 +13,7 @@ import 'package:cloud_firestore_platform_interface/src/method_channel/method_cha import 'test_common.dart'; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + initializeMethodChannel(); group("$MethodChannelDocumentReference()", () { MethodChannelDocumentReference _documentReference; diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart index 629ee5f9d8b5..68fd111e7914 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/query_test.dart @@ -7,6 +7,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_query.dart'; +import 'test_common.dart'; + const _kQueryPath = "test/collection"; class TestQuery extends MethodChannelQuery { @@ -17,7 +19,8 @@ class TestQuery extends MethodChannelQuery { } void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + initializeMethodChannel(); + group("$QueryPlatform()", () { test("parameters", () { _hasDefaultParameters(TestQuery._().parameters); diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart index 56ec01217045..4f028da1489d 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_common.dart @@ -7,12 +7,23 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_firestore.dart'; +import 'test_firestore_message_codec.dart'; typedef MethodCallCallback = dynamic Function(MethodCall methodCall); const kCollectionId = "test"; const kDocumentId = "document"; +void initializeMethodChannel() { + // Install the Codec that is able to decode FieldValues. + MethodChannelFirestore.channel = MethodChannel( + 'plugins.flutter.io/cloud_firestore', + StandardMethodCodec(TestFirestoreMessageCodec()), + ); + + TestWidgetsFlutterBinding.ensureInitialized(); +} + void handleMethodCall(MethodCallCallback methodCallCallback) => MethodChannelFirestore.channel.setMockMethodCallHandler((call) async { expect( diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_firestore_message_codec.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_firestore_message_codec.dart new file mode 100644 index 000000000000..9e8824895770 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/test_firestore_message_codec.dart @@ -0,0 +1,54 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter/foundation.dart'; + +import 'package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart'; + +/// This codec is able to decode FieldValues. +/// This ability is only required in tests, hence why +/// those values are only decoded in tests. +class TestFirestoreMessageCodec extends FirestoreMessageCodec { + /// Constructor. + const TestFirestoreMessageCodec(); + + static const int _kArrayUnion = 132; + static const int _kArrayRemove = 133; + static const int _kDelete = 134; + static const int _kServerTimestamp = 135; + + static const int _kIncrementDouble = 137; + static const int _kIncrementInteger = 138; + + @override + dynamic readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + // The following cases are only used by Unit Tests, and not by actual application + // code paths. + case _kArrayUnion: + final List value = readValue(buffer); + return FieldValuePlatform( + FieldValueFactoryPlatform.instance.arrayUnion(value)); + case _kArrayRemove: + final List value = readValue(buffer); + return FieldValuePlatform( + FieldValueFactoryPlatform.instance.arrayRemove(value)); + case _kDelete: + return FieldValuePlatform(FieldValueFactoryPlatform.instance.delete()); + case _kServerTimestamp: + return FieldValuePlatform( + FieldValueFactoryPlatform.instance.serverTimestamp()); + case _kIncrementDouble: + final double value = readValue(buffer); + return FieldValuePlatform( + FieldValueFactoryPlatform.instance.increment(value)); + case _kIncrementInteger: + final int value = readValue(buffer); + return FieldValuePlatform( + FieldValueFactoryPlatform.instance.increment(value)); + default: + return super.readValueOfType(type, buffer); + } + } +} diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart index 0adea06ee2b9..2778a6b538ce 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/test/transaction_test.dart @@ -8,7 +8,6 @@ import 'package:mockito/mockito.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_transaction.dart'; import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value_factory.dart'; -import 'package:cloud_firestore_platform_interface/src/method_channel/method_channel_field_value.dart'; import 'test_common.dart'; @@ -17,11 +16,12 @@ class MockDocumentReference extends Mock implements DocumentReferencePlatform {} const _kTransactionId = 1022; void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - final MethodChannelFieldValue mockFieldValue = - MethodChannelFieldValueFactory().increment(2.0); + initializeMethodChannel(); - group("$MethodChannelTransaction()", () { + final FieldValuePlatform mockFieldValue = + FieldValuePlatform(MethodChannelFieldValueFactory().increment(2.0)); + + group("MethodChannelTransaction()", () { TransactionPlatform transaction; final mockDocumentReference = MockDocumentReference(); when(mockDocumentReference.path).thenReturn("$kCollectionId/$kDocumentId"); diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index bc4f9f0af8ab..1d6145c5c6c1 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -31,8 +31,9 @@ class CodecUtility { /// Encodes a value from its proper type to a serialized version. static dynamic valueEncode(dynamic value) { - if (value is FieldValueWeb) { - return value.data; + if (value is FieldValuePlatform) { + FieldValueWeb delegate = FieldValuePlatform.getDelegate(value); + return delegate.data; } else if (value is Timestamp) { return value.toDate(); } else if (value is GeoPoint) { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart index 4fd4a9eeac84..ea4c1783cb4b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -12,8 +12,7 @@ import 'package:firebase/firestore.dart' as web; import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; import 'package:cloud_firestore_web/src/document_reference_web.dart'; - -class MockFieldValue extends Mock implements FieldValuePlatform {} +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; class MockGeoPoint extends Mock implements GeoPoint {} @@ -27,6 +26,9 @@ class MockWebBlob extends Mock implements web.Blob {} void main() { group("$CodecUtility()", () { + final FieldValuePlatform mockFieldValue = + FieldValuePlatform(FieldValueFactoryWeb().increment(2.0)); + setUp(() { js.context['firebase'] = js.JsObject.jsify({ 'firestore': js.JsObject.jsify({ @@ -38,11 +40,10 @@ void main() { }) }); }); + test("encodeMapData", () { expect(CodecUtility.encodeMapData(null), isNull); - //FieldValuePlatform - final mockFieldValue = MockFieldValue(); CodecUtility.encodeMapData({'test': mockFieldValue}); final timeStamp = Timestamp.now(); @@ -84,7 +85,6 @@ void main() { expect(CodecUtility.encodeArrayData(null), isNull); //FieldValuePlatform - final mockFieldValue = MockFieldValue(); CodecUtility.encodeArrayData([mockFieldValue]); final timeStamp = Timestamp.now(); From 48e5ba31eba3c056f98224ff0b837557e014298a Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 6 Feb 2020 08:47:30 +0000 Subject: [PATCH 136/144] Use published version of `cloud_firestore_platform_interface` --- packages/cloud_firestore/cloud_firestore/pubspec.yaml | 3 +-- packages/cloud_firestore/cloud_firestore_web/pubspec.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index ae90f494929d..858d18cef6e7 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -21,8 +21,7 @@ dependencies: sdk: flutter meta: "^1.0.5" firebase_core: "^0.4.0" - cloud_firestore_platform_interface: - path: ../cloud_firestore_platform_interface + cloud_firestore_platform_interface: "^1.0.0" cloud_firestore_web: path: ../cloud_firestore_web diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml index c77a80ec29ea..1e7fa80cf26b 100644 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -19,8 +19,7 @@ dependencies: http_parser: ^3.1.3 meta: ^1.1.7 firebase_core: ^0.4.3+1 - cloud_firestore_platform_interface: - path: ../cloud_firestore_platform_interface + cloud_firestore_platform_interface: "^1.0.0" js: ^0.6.1 dev_dependencies: From 60ae8e794e6afd0f3ce2b23f78cae89cf34c8fe8 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 6 Feb 2020 09:05:27 +0000 Subject: [PATCH 137/144] Remove references of _web and update changelog --- .../cloud_firestore/CHANGELOG.md | 2 +- .../cloud_firestore/example/web/index.html | 23 -- .../cloud_firestore/pubspec.yaml | 4 - .../cloud_firestore_web/CHANGELOG.md | 3 - .../cloud_firestore_web/LICENSE | 27 -- .../cloud_firestore_web/README.md | 52 --- .../cloud_firestore_web/android/.gitignore | 8 - .../cloud_firestore_web/android/build.gradle | 33 -- .../android/gradle.properties | 2 - .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android/settings.gradle | 1 - .../android/src/main/AndroidManifest.xml | 3 - .../FirestoreWebPlugin.java | 15 - .../ios/cloud_firestore_web.podspec | 21 -- .../lib/firestore_web.dart | 96 ------ .../lib/src/collection_reference_web.dart | 193 ------------ .../lib/src/document_reference_web.dart | 66 ---- .../lib/src/field_value_factory_web.dart | 32 -- .../lib/src/field_value_web.dart | 16 - .../lib/src/query_web.dart | 298 ------------------ .../lib/src/transaction_web.dart | 65 ---- .../lib/src/utils/codec_utility.dart | 88 ------ .../src/utils/document_reference_utils.dart | 21 -- .../lib/src/write_batch_web.dart | 51 --- .../cloud_firestore_web/pubspec.yaml | 35 -- .../test/codec_utility_test.dart | 194 ------------ .../test/collection_reference_web_test.dart | 152 --------- .../test/document_reference_web_test.dart | 78 ----- .../test/field_value_factory_web_test.dart | 52 --- .../test/query_web_test.dart | 186 ----------- .../cloud_firestore_web/test/test_common.dart | 56 ---- .../test/transaction_web_test.dart | 56 ---- .../test/write_batch_web_test.dart | 38 --- 33 files changed, 1 insertion(+), 1971 deletions(-) delete mode 100644 packages/cloud_firestore/cloud_firestore/example/web/index.html delete mode 100644 packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md delete mode 100644 packages/cloud_firestore/cloud_firestore_web/LICENSE delete mode 100644 packages/cloud_firestore/cloud_firestore_web/README.md delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/.gitignore delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/build.gradle delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle.properties delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/settings.gradle delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml delete mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java delete mode 100644 packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/pubspec.yaml delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/test_common.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart delete mode 100644 packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore/CHANGELOG.md index 1c7d5610fd26..8ec5e31a8204 100644 --- a/packages/cloud_firestore/cloud_firestore/CHANGELOG.md +++ b/packages/cloud_firestore/cloud_firestore/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.13.1 -* Added support for Flutter Web +* Migrate to `cloud_firestore_platform_interface` ## 0.13.0+2 diff --git a/packages/cloud_firestore/cloud_firestore/example/web/index.html b/packages/cloud_firestore/cloud_firestore/example/web/index.html deleted file mode 100644 index d31bf55b8935..000000000000 --- a/packages/cloud_firestore/cloud_firestore/example/web/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - example - - - - - - - - diff --git a/packages/cloud_firestore/cloud_firestore/pubspec.yaml b/packages/cloud_firestore/cloud_firestore/pubspec.yaml index 858d18cef6e7..3b2af29f6834 100755 --- a/packages/cloud_firestore/cloud_firestore/pubspec.yaml +++ b/packages/cloud_firestore/cloud_firestore/pubspec.yaml @@ -13,8 +13,6 @@ flutter: pluginClass: CloudFirestorePlugin ios: pluginClass: FLTCloudFirestorePlugin - web: - default_package: cloud_firestore_web dependencies: flutter: @@ -22,8 +20,6 @@ dependencies: meta: "^1.0.5" firebase_core: "^0.4.0" cloud_firestore_platform_interface: "^1.0.0" - cloud_firestore_web: - path: ../cloud_firestore_web dev_dependencies: flutter_test: diff --git a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md deleted file mode 100644 index e53776993662..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.1.0 - -- Initial release \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/LICENSE b/packages/cloud_firestore/cloud_firestore_web/LICENSE deleted file mode 100644 index 000b4618d2bd..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 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. \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/README.md b/packages/cloud_firestore/cloud_firestore_web/README.md deleted file mode 100644 index b9d0e93f883d..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# cloud_firestore_web - -The web implementation of [`cloud_firestore`][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 `cloud_firestore` -plugin. - -_(This is only temporary: in the future we hope to make this package -an "endorsed" implementation of `cloud_firestore`, 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: - ... - cloud_firestore: ^0.13.1 - cloud_firestore_web: ^0.1.0 - ... -``` - -### Updating `index.html` - -Due to [this bug in dartdevc][2], you will need to manually add the Firebase -JavaScript files to your `index.html` file. - -In your app directory, edit `web/index.html` to add the line: - -```html - - ... - - - - - - -``` - -### Using the plugin - -Once you have added the `cloud_firebase_web` dependency to your pubspec, -you can use `package:cloud_firebase` as normal. - -[1]: ../cloud_firestore -[2]: https://github.com/dart-lang/sdk/issues/33979 diff --git a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore deleted file mode 100644 index c6cbe562a427..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle deleted file mode 100644 index e3db786e3805..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -group 'io.flutter.plugins.cloud_firestore_web' -version '1.0' - -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - } -} - -apply plugin: 'com.android.library' - -android { - compileSdkVersion 28 - - defaultConfig { - minSdkVersion 16 - } - lintOptions { - disable 'InvalidPackage' - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties deleted file mode 100644 index 3148384dab31..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 019065d1d650..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle deleted file mode 100644 index 6bbf9cba49da..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'cloud_firestore_web' diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml deleted file mode 100644 index ff4f493a984c..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java deleted file mode 100644 index af02befd488e..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.flutter.plugins.cloud_firestore_web; - -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.PluginRegistry.Registrar; - -/** FirebaseAuthWebPlugin */ -public class FirestoreWebPlugin implements FlutterPlugin { - @Override - public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {} - - public static void registerWith(Registrar registrar) {} - - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) {} -} diff --git a/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec b/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec deleted file mode 100644 index 2e9b05c81076..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec +++ /dev/null @@ -1,21 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'cloud_firestore_web' - s.version = '0.1.0' - s.summary = 'No-op implementation of cloud_firestore_web web plugin to avoid build issues on iOS' - s.description = <<-DESC - temp fake firebase_auth_web plugin - DESC - s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_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/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart deleted file mode 100644 index 0558b9b28597..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firebase.dart' as firebase; -import 'package:firebase/firestore.dart' show Firestore, Settings; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter_web_plugins/flutter_web_plugins.dart'; - -import 'package:cloud_firestore_web/src/collection_reference_web.dart'; -import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:cloud_firestore_web/src/query_web.dart'; -import 'package:cloud_firestore_web/src/transaction_web.dart'; -import 'package:cloud_firestore_web/src/write_batch_web.dart'; - -/// Web implementation for [FirestorePlatform] -/// delegates calls to firestore web plugin -class FirestoreWeb extends FirestorePlatform { - /// instance of Firestore from the web plugin - final Firestore _webFirestore; - - /// Called by PluginRegistry to register this plugin for Flutter Web - static void registerWith(Registrar registrar) { - FirestorePlatform.instance = FirestoreWeb(); - } - - /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance - /// If [app] is null then the created instance will use the default [FirebaseApp] - FirestoreWeb({FirebaseApp app}) - : _webFirestore = firebase - .firestore(firebase.app((app ?? FirebaseApp.instance).name)), - super(app: app ?? FirebaseApp.instance) { - FieldValueFactoryPlatform.instance = FieldValueFactoryWeb(); - } - - @override - FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); - - @override - CollectionReferencePlatform collection(String path) { - return CollectionReferenceWeb(this, _webFirestore, path.split('/')); - } - - @override - QueryPlatform collectionGroup(String path) { - return QueryWeb(this, path, _webFirestore.collectionGroup(path), - isCollectionGroup: true); - } - - @override - DocumentReferencePlatform document(String path) => - DocumentReferenceWeb(_webFirestore, this, path.split('/')); - - @override - WriteBatchPlatform batch() => WriteBatchWeb(_webFirestore.batch()); - - @override - Future enablePersistence(bool enable) async { - if (enable) { - await _webFirestore.enablePersistence(); - } - } - - @override - Future settings( - {bool persistenceEnabled, - String host, - bool sslEnabled, - int cacheSizeBytes}) async { - if (host != null && sslEnabled != null) { - _webFirestore.settings(Settings( - cacheSizeBytes: cacheSizeBytes ?? 40000000, - host: host, - ssl: sslEnabled)); - } else { - _webFirestore - .settings(Settings(cacheSizeBytes: cacheSizeBytes ?? 40000000)); - } - if (persistenceEnabled) { - await _webFirestore.enablePersistence(); - } - } - - @override - Future> runTransaction( - TransactionHandler transactionHandler, - {Duration timeout = const Duration(seconds: 5)}) async { - Map result; - await _webFirestore.runTransaction((transaction) async { - result = await transactionHandler(TransactionWeb(transaction, this)); - }).timeout(timeout); - return result is Map ? result : {}; - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart deleted file mode 100644 index a75131e7e2b9..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:meta/meta.dart'; - -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:cloud_firestore_web/src/query_web.dart'; - -/// Web implementation for Firestore [CollectionReferencePlatform] -class CollectionReferenceWeb extends CollectionReferencePlatform { - /// instance of Firestore from the web plugin - final web.Firestore webFirestore; - final FirestorePlatform _firestorePlatform; - final List pathComponents; - // disabling lint as it's only visible for testing - @visibleForTesting - QueryWeb queryDelegate; // ignore: public_member_api_docs - - /// Creates an instance of [CollectionReferenceWeb] which represents path - /// at [pathComponents] and uses implementation of [webFirestore] - CollectionReferenceWeb( - this._firestorePlatform, this.webFirestore, this.pathComponents) - : queryDelegate = QueryWeb( - _firestorePlatform, - pathComponents.join("/"), - webFirestore.collection(pathComponents.join("/")), - ), - super(_firestorePlatform, pathComponents); - - @override - DocumentReferencePlatform parent() { - if (pathComponents.length < 2) { - return null; - } - return DocumentReferenceWeb( - webFirestore, - firestore, - (List.from(pathComponents)..removeLast()), - ); - } - - @override - DocumentReferencePlatform document([String path]) { - List childPath; - if (path == null) { - web.DocumentReference doc = - webFirestore.collection(pathComponents.join('/')).doc(); - childPath = doc.path.split('/'); - } else { - childPath = List.from(pathComponents)..addAll(path.split(('/'))); - } - return DocumentReferenceWeb( - webFirestore, - firestore, - childPath, - ); - } - - @override - Future add(Map data) async { - final DocumentReferencePlatform newDocument = document(); - await newDocument.setData(data); - return newDocument; - } - - @override - Map buildArguments() => queryDelegate.buildArguments(); - - @override - QueryPlatform endAt(List values) { - _resetQueryDelegate(); - return queryDelegate.endAt(values); - } - - @override - QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { - _resetQueryDelegate(); - return queryDelegate.endAtDocument(documentSnapshot); - } - - @override - QueryPlatform endBefore(List values) { - _resetQueryDelegate(); - return queryDelegate.endBefore(values); - } - - @override - QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { - _resetQueryDelegate(); - return queryDelegate.endBeforeDocument(documentSnapshot); - } - - @override - FirestorePlatform get firestore => _firestorePlatform; - - @override - Future getDocuments({ - Source source = Source.serverAndCache, - }) => - queryDelegate.getDocuments(source: source); - - @override - String get id => pathComponents.isEmpty ? null : pathComponents.last; - - @override - bool get isCollectionGroup => false; - - @override - QueryPlatform limit(int length) { - _resetQueryDelegate(); - return queryDelegate.limit(length); - } - - @override - QueryPlatform orderBy( - field, { - bool descending = false, - }) { - _resetQueryDelegate(); - return queryDelegate.orderBy(field, descending: descending); - } - - @override - Map get parameters => queryDelegate.parameters; - - @override - String get path => pathComponents.join("/"); - - @override - CollectionReferencePlatform reference() => queryDelegate.reference(); - - @override - Stream snapshots({ - bool includeMetadataChanges = false, - }) => - queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); - - @override - QueryPlatform startAfter(List values) { - _resetQueryDelegate(); - return queryDelegate.startAfter(values); - } - - @override - QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { - _resetQueryDelegate(); - return queryDelegate.startAfterDocument(documentSnapshot); - } - - @override - QueryPlatform startAt(List values) { - _resetQueryDelegate(); - return queryDelegate.startAt(values); - } - - @override - QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { - _resetQueryDelegate(); - return queryDelegate.startAtDocument(documentSnapshot); - } - - @override - QueryPlatform where( - field, { - isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull, - }) { - _resetQueryDelegate(); - return queryDelegate.where(field, - isEqualTo: isEqualTo, - isLessThan: isLessThan, - isLessThanOrEqualTo: isLessThanOrEqualTo, - isGreaterThan: isGreaterThan, - isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, - arrayContains: arrayContains, - arrayContainsAny: arrayContainsAny, - whereIn: whereIn, - isNull: isNull); - } - - void _resetQueryDelegate() => - queryDelegate = queryDelegate.resetQueryDelegate(); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart deleted file mode 100644 index 373ae6f83261..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/collection_reference_web.dart'; -import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; -import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; - -/// Web implementation for firestore [DocumentReferencePlatform] -class DocumentReferenceWeb extends DocumentReferencePlatform { - /// instance of Firestore from the web plugin - final web.Firestore firestoreWeb; - - /// instance of DocumentReference from the web plugin - final web.DocumentReference delegate; - - /// Creates an instance of [CollectionReferenceWeb] which represents path - /// at [pathComponents] and uses implementation of [firestoreWeb] - DocumentReferenceWeb( - this.firestoreWeb, - FirestorePlatform firestore, - List pathComponents, - ) : delegate = firestoreWeb.doc(pathComponents.join("/")), - super(firestore, pathComponents); - - @override - Future setData( - Map data, { - bool merge = false, - }) => - delegate.set( - CodecUtility.encodeMapData(data), - web.SetOptions(merge: merge), - ); - - @override - Future updateData(Map data) => - delegate.update(data: CodecUtility.encodeMapData(data)); - - @override - Future get({ - Source source = Source.serverAndCache, - }) async { - return fromWebDocumentSnapshotToPlatformDocumentSnapshot( - await delegate.get(), this.firestore); - } - - @override - Future delete() => delegate.delete(); - - @override - Stream snapshots({ - bool includeMetadataChanges = false, - }) { - Stream querySnapshots = delegate.onSnapshot; - if (includeMetadataChanges) { - querySnapshots = delegate.onMetadataChangesSnapshot; - } - return querySnapshots.map((webSnapshot) => - fromWebDocumentSnapshotToPlatformDocumentSnapshot( - webSnapshot, this.firestore)); - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart deleted file mode 100644 index cfae0922dfa1..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:js/js_util.dart'; - -import 'package:cloud_firestore_web/src/field_value_web.dart'; - -/// An implementation of [FieldValueFactoryPlatform] which builds [FieldValuePlatform] -/// instance that is [jsify] friendly -class FieldValueFactoryWeb extends FieldValueFactoryPlatform { - @override - FieldValuePlatform arrayRemove(List elements) => - FieldValueWeb(web.FieldValue.arrayRemove(elements)); - - @override - FieldValuePlatform arrayUnion(List elements) => - FieldValueWeb(web.FieldValue.arrayUnion(elements)); - - @override - FieldValuePlatform delete() => FieldValueWeb(web.FieldValue.delete()); - - @override - FieldValuePlatform increment(num value) => - FieldValueWeb(web.FieldValue.increment(value)); - - @override - FieldValuePlatform serverTimestamp() => - FieldValueWeb(web.FieldValue.serverTimestamp()); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart deleted file mode 100644 index c3e7e5c38881..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -/// Implementation of [FieldValuePlatform] that is compatible with -/// firestore web plugin -class FieldValueWeb extends FieldValuePlatform { - /// The js-interop delegate for this [FieldValuePlatform] - web.FieldValue data; - - /// Constructor. - FieldValueWeb(this.data) : super(); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart deleted file mode 100644 index bd677246ab0a..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; - -/// Web implementation for firestore [QueryPlatform] -class QueryWeb extends QueryPlatform { - final web.Query _webQuery; - final FirestorePlatform _firestore; - final bool _isCollectionGroup; - final String _path; - final List _orderByKeys; - static const _kChangeTypeAdded = "added"; - static const _kChangeTypeModified = "modified"; - static const _kChangeTypeRemoved = "removed"; - - /// Builds an instance of [QueryWeb] using [_path] & [_webQuery] - /// to delegate queries to underlying firestore web plugin - QueryWeb( - this._firestore, - this._path, - this._webQuery, { - bool isCollectionGroup, - List orderByKeys, - }) : this._isCollectionGroup = isCollectionGroup ?? false, - this._orderByKeys = orderByKeys ?? [], - super( - firestore: _firestore, - pathComponents: _path.split('/'), - isCollectionGroup: isCollectionGroup, - ); - - @override - Stream snapshots({ - bool includeMetadataChanges = false, - }) { - assert(_webQuery != null); - Stream querySnapshots = _webQuery.onSnapshot; - if (includeMetadataChanges) { - querySnapshots = _webQuery.onSnapshotMetadata; - } - return querySnapshots.map(_webQuerySnapshotToQuerySnapshot); - } - - @override - Future getDocuments({ - Source source = Source.serverAndCache, - }) async { - assert(_webQuery != null); - return _webQuerySnapshotToQuerySnapshot(await _webQuery.get()); - } - - @override - Map buildArguments() => Map(); - - @override - QueryPlatform endAt(List values) => QueryWeb( - this._firestore, - this._path, - _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, - isCollectionGroup: _isCollectionGroup, - ); - - @override - QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { - assert(_webQuery != null && _orderByKeys.isNotEmpty); - return QueryWeb( - this._firestore, - this._path, - _webQuery.endAt( - fieldValues: - _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), - isCollectionGroup: _isCollectionGroup); - } - - @override - QueryPlatform endBefore(List values) => QueryWeb( - this._firestore, - this._path, - _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, - isCollectionGroup: _isCollectionGroup, - ); - - @override - QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { - assert(_webQuery != null && _orderByKeys.isNotEmpty); - return QueryWeb( - this._firestore, - this._path, - _webQuery.endBefore( - fieldValues: - _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), - isCollectionGroup: _isCollectionGroup); - } - - @override - FirestorePlatform get firestore => _firestore; - - @override - bool get isCollectionGroup => _isCollectionGroup; - - @override - QueryPlatform limit(int length) => QueryWeb( - this._firestore, - this._path, - _webQuery != null ? _webQuery.limit(length) : null, - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup, - ); - - @override - QueryPlatform orderBy( - field, { - bool descending = false, - }) { - dynamic usableField = field; - if (field == FieldPath.documentId) { - usableField = web.FieldPath.documentId(); - } - return QueryWeb( - this._firestore, - this._path, - _webQuery.orderBy(usableField, descending ? "desc" : "asc"), - orderByKeys: _orderByKeys..add(usableField), - isCollectionGroup: _isCollectionGroup, - ); - } - - @override - String get path => this._path; - - @override - List get pathComponents => this._path.split("/"); - - @override - CollectionReferencePlatform reference() => firestore.collection(_path); - - @override - QueryPlatform startAfter(List values) => QueryWeb( - this._firestore, - this._path, - _webQuery.startAfter(fieldValues: values), - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup, - ); - - @override - QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { - assert(_webQuery != null && _orderByKeys.isNotEmpty); - return QueryWeb( - this._firestore, - this._path, - _webQuery.startAfter( - fieldValues: - _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup); - } - - @override - QueryPlatform startAt(List values) => QueryWeb( - this._firestore, - this._path, - _webQuery.startAt(fieldValues: values), - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup, - ); - - @override - QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { - assert(_webQuery != null && _orderByKeys.isNotEmpty); - return QueryWeb( - this._firestore, - this._path, - _webQuery.startAt( - fieldValues: - _orderByKeys.map((key) => documentSnapshot.data[key]).toList(), - ), - orderByKeys: _orderByKeys, - isCollectionGroup: _isCollectionGroup, - ); - } - - @override - QueryPlatform where( - field, { - isEqualTo, - isLessThan, - isLessThanOrEqualTo, - isGreaterThan, - isGreaterThanOrEqualTo, - arrayContains, - List arrayContainsAny, - List whereIn, - bool isNull, - }) { - assert(field is String || field is FieldPath, - 'Supported [field] types are [String] and [FieldPath].'); - assert(_webQuery != null); - dynamic usableField = field; - if (field == FieldPath.documentId) { - usableField = web.FieldPath.documentId(); - } - web.Query query = _webQuery; - - if (isEqualTo != null) { - query = query.where(usableField, "==", isEqualTo); - } - if (isLessThan != null) { - query = query.where(usableField, "<", isLessThan); - } - if (isLessThanOrEqualTo != null) { - query = query.where(usableField, "<=", isLessThanOrEqualTo); - } - if (isGreaterThan != null) { - query = query.where(usableField, ">", isGreaterThan); - } - if (isGreaterThanOrEqualTo != null) { - query = query.where(usableField, ">=", isGreaterThanOrEqualTo); - } - if (arrayContains != null) { - query = query.where(usableField, "array-contains", arrayContains); - } - if (arrayContainsAny != null) { - assert(arrayContainsAny.length <= 10, - "array contains can have maximum of 10 items"); - query = query.where(usableField, "array-contains-any", arrayContainsAny); - } - if (whereIn != null) { - assert( - whereIn.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(usableField, "in", whereIn); - } - if (isNull != null) { - assert( - isNull, - 'isNull can only be set to true. ' - 'Use isEqualTo to filter on non-null values.'); - query = query.where(usableField, "==", null); - } - return QueryWeb(this._firestore, this._path, query, - orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); - } - - QuerySnapshotPlatform _webQuerySnapshotToQuerySnapshot( - web.QuerySnapshot webSnapshot, - ) { - return QuerySnapshotPlatform( - webSnapshot.docs - .map((webSnapshot) => - fromWebDocumentSnapshotToPlatformDocumentSnapshot( - webSnapshot, this._firestore)) - .toList(), - webSnapshot.docChanges().map(_webChangeToChange).toList(), - _webMetadataToMetada(webSnapshot.metadata)); - } - - DocumentChangePlatform _webChangeToChange(web.DocumentChange webChange) { - return DocumentChangePlatform( - _fromString(webChange.type), - webChange.oldIndex, - webChange.newIndex, - fromWebDocumentSnapshotToPlatformDocumentSnapshot( - webChange.doc, this._firestore)); - } - - DocumentChangeType _fromString(String item) { - switch (item.toLowerCase()) { - case _kChangeTypeAdded: - return DocumentChangeType.added; - case _kChangeTypeModified: - return DocumentChangeType.modified; - case _kChangeTypeRemoved: - return DocumentChangeType.removed; - default: - throw ArgumentError("Invalid type"); - } - } - - SnapshotMetadataPlatform _webMetadataToMetada( - web.SnapshotMetadata webMetadata) { - return SnapshotMetadataPlatform( - webMetadata.hasPendingWrites, - webMetadata.fromCache, - ); - } - - @override - Map get parameters => Map(); - - /// Returns a clean clone of this QueryWeb. - QueryWeb resetQueryDelegate() => - QueryWeb(firestore, pathComponents.join("/"), _webQuery); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart deleted file mode 100644 index e93e0c8ef715..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; -import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; - -/// A web specific for [Transaction] -class TransactionWeb extends TransactionPlatform { - final web.Transaction _webTransaction; - @override - FirestorePlatform firestore; - - /// Constructor. - TransactionWeb(this._webTransaction, this.firestore) : super(firestore); - - @override - Future delete(DocumentReferencePlatform documentReference) async { - assert(documentReference is DocumentReferenceWeb); - await _webTransaction - .delete((documentReference as DocumentReferenceWeb).delegate); - } - - @override - Future get( - DocumentReferencePlatform documentReference, - ) async { - assert(documentReference is DocumentReferenceWeb); - final webSnapshot = await _webTransaction - .get((documentReference as DocumentReferenceWeb).delegate); - return fromWebDocumentSnapshotToPlatformDocumentSnapshot( - webSnapshot, this.firestore); - } - - @override - Future set( - DocumentReferencePlatform documentReference, - Map data, - ) async { - assert(documentReference is DocumentReferenceWeb); - await _webTransaction.set( - (documentReference as DocumentReferenceWeb).delegate, - CodecUtility.encodeMapData(data)); - } - - @override - Future update( - DocumentReferencePlatform documentReference, - Map data, - ) async { - assert(documentReference is DocumentReferenceWeb); - await _webTransaction.update( - (documentReference as DocumentReferenceWeb).delegate, - data: CodecUtility.encodeMapData(data)); - } - - @override - Future finish() { - return Future.value(); - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart deleted file mode 100644 index 1d6145c5c6c1..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:cloud_firestore_web/src/field_value_web.dart'; - -/// Class containing static utility methods to encode/decode firestore data. -class CodecUtility { - /// Encodes a Map of values from their proper types to a serialized version. - static Map encodeMapData(Map data) { - if (data == null) { - return null; - } - Map output = Map.from(data); - output.updateAll((key, value) => valueEncode(value)); - return output; - } - - /// Encodes an Array of values from their proper types to a serialized version. - static List encodeArrayData(List data) { - if (data == null) { - return null; - } - return List.from(data).map(valueEncode).toList(); - } - - /// Encodes a value from its proper type to a serialized version. - static dynamic valueEncode(dynamic value) { - if (value is FieldValuePlatform) { - FieldValueWeb delegate = FieldValuePlatform.getDelegate(value); - return delegate.data; - } else if (value is Timestamp) { - return value.toDate(); - } else if (value is GeoPoint) { - return web.GeoPoint(value.latitude, value.longitude); - } else if (value is Blob) { - return web.Blob.fromUint8Array(value.bytes); - } else if (value is DocumentReferenceWeb) { - return value.delegate; - } else if (value is Map) { - return encodeMapData(value); - } else if (value is List) { - return encodeArrayData(value); - } - return value; - } - - /// Decodes the values on an incoming Map to their proper types. - static Map decodeMapData(Map data) { - if (data == null) { - return null; - } - Map output = Map.from(data); - output.updateAll((key, value) => valueDecode(value)); - return output; - } - - /// Decodes the values on an incoming Array to their proper types. - static List decodeArrayData(List data) { - if (data == null) { - return null; - } - return List.from(data).map(valueDecode).toList(); - } - - /// Decodes an incoming value to its proper type. - static dynamic valueDecode(dynamic value) { - if (value is web.GeoPoint) { - return GeoPoint(value.latitude, value.longitude); - } else if (value is DateTime) { - return Timestamp.fromDate(value); - } else if (value is web.Blob) { - return Blob(value.toUint8Array()); - } else if (value is web.DocumentReference) { - return (FirestorePlatform.instance as FirestoreWeb).document(value.path); - } else if (value is Map) { - return decodeMapData(value); - } else if (value is List) { - return decodeArrayData(value); - } - return value; - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart deleted file mode 100644 index e723c0025375..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; - -/// Builds [DocumentSnapshotPlatform] instance form web snapshot instance -DocumentSnapshotPlatform fromWebDocumentSnapshotToPlatformDocumentSnapshot( - web.DocumentSnapshot webSnapshot, FirestorePlatform firestore) { - return DocumentSnapshotPlatform( - webSnapshot.ref.path, - CodecUtility.decodeMapData(webSnapshot.data()), - SnapshotMetadataPlatform( - webSnapshot.metadata.hasPendingWrites, - webSnapshot.metadata.fromCache, - ), - firestore); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart deleted file mode 100644 index 7d76b20b8fda..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; - -/// A web specific for [WriteBatch] -class WriteBatchWeb extends WriteBatchPlatform { - final web.WriteBatch _delegate; - - /// Constructor. - WriteBatchWeb(this._delegate); - - @override - Future commit() async { - await _delegate.commit(); - } - - @override - void delete(DocumentReferencePlatform document) { - assert(document is DocumentReferenceWeb); - _delegate.delete((document as DocumentReferenceWeb).delegate); - } - - @override - void setData( - DocumentReferencePlatform document, - Map data, { - bool merge = false, - }) { - assert(document is DocumentReferenceWeb); - _delegate.set( - (document as DocumentReferenceWeb).delegate, - CodecUtility.encodeMapData(data), - merge ? web.SetOptions(merge: merge) : null); - } - - @override - void updateData( - DocumentReferencePlatform document, - Map data, - ) { - assert(document is DocumentReferenceWeb); - _delegate.update((document as DocumentReferenceWeb).delegate, - data: CodecUtility.encodeMapData(data)); - } -} diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml deleted file mode 100644 index 1e7fa80cf26b..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: cloud_firestore_web -description: The web implementation of cloud_firestore -homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_web -version: 0.1.0 - -flutter: - plugin: - platforms: - web: - pluginClass: FirestoreWeb - fileName: firestore_web.dart - -dependencies: - flutter: - sdk: flutter - flutter_web_plugins: - sdk: flutter - firebase: ^7.0.0 - http_parser: ^3.1.3 - meta: ^1.1.7 - firebase_core: ^0.4.3+1 - cloud_firestore_platform_interface: "^1.0.0" - js: ^0.6.1 - -dev_dependencies: - flutter_test: - sdk: flutter - firebase_core_platform_interface: ^1.0.0 - firebase_core_web: ^0.1.1 - mockito: ^4.1.1 - -environment: - sdk: ">=2.1.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" - diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart deleted file mode 100644 index ea4c1783cb4b..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn("chrome") -import 'dart:typed_data'; -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'dart:js' as js; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; - -class MockGeoPoint extends Mock implements GeoPoint {} - -class MockBlob extends Mock implements Blob {} - -class MockDocumentReferenceWeb extends Mock implements DocumentReferenceWeb {} - -class MockWebGeoPoint extends Mock implements web.GeoPoint {} - -class MockWebBlob extends Mock implements web.Blob {} - -void main() { - group("$CodecUtility()", () { - final FieldValuePlatform mockFieldValue = - FieldValuePlatform(FieldValueFactoryWeb().increment(2.0)); - - setUp(() { - js.context['firebase'] = js.JsObject.jsify({ - 'firestore': js.JsObject.jsify({ - 'GeoPoint': - js.allowInterop((latitude, longitude) => MockWebGeoPoint()), - 'Blob': js.JsObject.jsify({ - 'fromUint8Array': js.allowInterop((_) => MockWebBlob()) - }) - }) - }); - }); - - test("encodeMapData", () { - expect(CodecUtility.encodeMapData(null), isNull); - //FieldValuePlatform - CodecUtility.encodeMapData({'test': mockFieldValue}); - - final timeStamp = Timestamp.now(); - final result = CodecUtility.encodeMapData({'test': timeStamp}); - expect(result['test'], isInstanceOf()); - - //GeoPoint - final mockGeoPoint = MockGeoPoint(); - CodecUtility.encodeMapData({'test': mockGeoPoint}); - verify(mockGeoPoint.latitude); - verify(mockGeoPoint.longitude); - - //Blob - final mockBlob = MockBlob(); - CodecUtility.encodeMapData({'test': mockBlob}); - verify(mockBlob.bytes); - - //DocumentReferenceWeb - final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); - CodecUtility.encodeMapData({'test': mockDocumentReferenceWeb}); - verify(mockDocumentReferenceWeb.delegate); - - //Map - reset(mockDocumentReferenceWeb); - CodecUtility.encodeMapData({ - 'test': {'test2': mockDocumentReferenceWeb} - }); - verify(mockDocumentReferenceWeb.delegate); - - //List - reset(mockDocumentReferenceWeb); - CodecUtility.encodeMapData({ - 'test': [mockDocumentReferenceWeb] - }); - verify(mockDocumentReferenceWeb.delegate); - }); - - test("encodeArrayData", () { - expect(CodecUtility.encodeArrayData(null), isNull); - - //FieldValuePlatform - CodecUtility.encodeArrayData([mockFieldValue]); - - final timeStamp = Timestamp.now(); - final result = CodecUtility.encodeArrayData([timeStamp]); - expect(result.first, isInstanceOf()); - - //GeoPoint - final mockGeoPoint = MockGeoPoint(); - CodecUtility.encodeArrayData([mockGeoPoint]); - verify(mockGeoPoint.latitude); - verify(mockGeoPoint.longitude); - - //Blob - final mockBlob = MockBlob(); - CodecUtility.encodeArrayData([mockBlob]); - verify(mockBlob.bytes); - - //DocumentReferenceWeb - final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); - CodecUtility.encodeArrayData([mockDocumentReferenceWeb]); - verify(mockDocumentReferenceWeb.delegate); - - //Map - reset(mockDocumentReferenceWeb); - CodecUtility.encodeArrayData([ - {'test2': mockDocumentReferenceWeb} - ]); - verify(mockDocumentReferenceWeb.delegate); - - //List - reset(mockDocumentReferenceWeb); - CodecUtility.encodeArrayData([ - [mockDocumentReferenceWeb] - ]); - verify(mockDocumentReferenceWeb.delegate); - }); - - test("decodeMapData", () { - expect(CodecUtility.decodeMapData(null), isNull); - - //Blob - final mockWebBlob = MockWebBlob(); - when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); - expect(CodecUtility.decodeMapData({'test': mockWebBlob})['test'], - isInstanceOf()); - verify(mockWebBlob.toUint8Array()); - - final date = DateTime.now(); - expect(CodecUtility.decodeMapData({'test': date})['test'], - isInstanceOf()); - - //GeoPoint - final mockWebGeoPoint = MockWebGeoPoint(); - expect(CodecUtility.decodeMapData({'test': mockWebGeoPoint})['test'], - isInstanceOf()); - - //Map - expect( - CodecUtility.decodeMapData({ - 'test': {'test1': mockWebGeoPoint} - })['test']['test1'], - isInstanceOf()); - - //List - expect( - CodecUtility.decodeMapData({ - 'test': [mockWebGeoPoint] - })['test'] - .first, - isInstanceOf()); - }); - - test("decodeArrayData", () { - expect(CodecUtility.decodeArrayData(null), isNull); - - //Blob - final mockWebBlob = MockWebBlob(); - when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); - expect(CodecUtility.decodeArrayData([mockWebBlob]).first, - isInstanceOf()); - verify(mockWebBlob.toUint8Array()); - - final date = DateTime.now(); - expect(CodecUtility.decodeArrayData([date]).first, - isInstanceOf()); - - //GeoPoint - final mockWebGeoPoint = MockWebGeoPoint(); - expect(CodecUtility.decodeArrayData([mockWebGeoPoint]).first, - isInstanceOf()); - - //Map - expect( - CodecUtility.decodeArrayData([ - {'test1': mockWebGeoPoint} - ]).first['test1'], - isInstanceOf()); - - //List - expect( - CodecUtility.decodeArrayData([ - [mockWebGeoPoint] - ]).first.first, - isInstanceOf()); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart deleted file mode 100644 index 6b2c8c19973a..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn('chrome') -import 'dart:js' as js; - -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/src/collection_reference_web.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'test_common.dart'; - -void main() { - group("$CollectionReferenceWeb()", () { - final mockDocumentReference = MockWebDocumentReference(); - final mockCollectionReference = MockWebCollectionReference(); - final anotherMockDocumentReference = MockWebDocumentReference(); - CollectionReferenceWeb collectionReference; - setUp(() { - final mockFirestoreWeb = mockFirestore(); - collectionReference = CollectionReferenceWeb(FirestorePlatform.instance, - js.context['firebase']['firestore'](""), [kCollectionId]); - collectionReference.queryDelegate = MockQueryWeb(); - when(mockFirestoreWeb.doc(any)).thenReturn(mockDocumentReference); - - // Used for document creation... - when(mockFirestoreWeb.collection(any)) - .thenReturn(mockCollectionReference); - when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); - when(mockCollectionReference.doc(null)) - .thenReturn(anotherMockDocumentReference); - - when(anotherMockDocumentReference.path).thenReturn("test/asdf"); - - when(collectionReference.queryDelegate.resetQueryDelegate()) - .thenReturn(collectionReference.queryDelegate); - }); - - test("parent", () { - expect(collectionReference.parent(), isNull); - expect( - CollectionReferenceWeb( - FirestorePlatform.instance, - js.context['firebase']['firestore'](""), - [kCollectionId, kCollectionId, kCollectionId]).parent(), - isInstanceOf()); - }); - - test("document", () { - final newDocument = collectionReference.document(); - expect(newDocument.path.split("/").length, - collectionReference.pathComponents.length + 1); - final newDocumentWithPath = collectionReference.document("test1"); - expect(newDocumentWithPath.path, - equals("${collectionReference.path}/test1")); - }); - - test("add", () async { - expect(await collectionReference.add({}), - isInstanceOf()); - }); - - test("buildArguments", () async { - collectionReference.buildArguments(); - verify(collectionReference.queryDelegate.buildArguments()); - }); - - test("getDocuments", () async { - await collectionReference.getDocuments(); - verify(collectionReference.queryDelegate.getDocuments()); - }); - - test("reference", () async { - collectionReference.reference(); - verify(collectionReference.queryDelegate.reference()); - }); - - test("snapshots", () async { - collectionReference.snapshots(includeMetadataChanges: true); - verify(collectionReference.queryDelegate - .snapshots(includeMetadataChanges: true)); - collectionReference.snapshots(includeMetadataChanges: false); - verify(collectionReference.queryDelegate - .snapshots(includeMetadataChanges: false)); - }); - - test("where", () async { - collectionReference.where("test"); - verify(collectionReference.queryDelegate.where("test")); - }); - - test("startAt", () async { - collectionReference.startAt([]); - verify(collectionReference.queryDelegate.startAt([])); - }); - - test("startAfter", () async { - collectionReference.startAfter([]); - verify(collectionReference.queryDelegate.startAfter([])); - }); - - test("endBefore", () async { - collectionReference.endBefore([]); - verify(collectionReference.queryDelegate.endBefore([])); - }); - - test("endAt", () async { - collectionReference.endAt([]); - verify(collectionReference.queryDelegate.endAt([])); - }); - - test("limit", () async { - collectionReference.limit(1); - verify(collectionReference.queryDelegate.limit(1)); - }); - - test("orderBy", () async { - collectionReference.orderBy("test"); - verify(collectionReference.queryDelegate.orderBy("test")); - collectionReference.orderBy("test", descending: true); - verify( - collectionReference.queryDelegate.orderBy("test", descending: true)); - }); - - test("startAfterDocument", () async { - final mockSnapshot = MockDocumentSnapshot(); - collectionReference.startAfterDocument(mockSnapshot); - verify( - collectionReference.queryDelegate.startAfterDocument(mockSnapshot)); - }); - - test("startAtDocument", () async { - final mockSnapshot = MockDocumentSnapshot(); - collectionReference.startAtDocument(mockSnapshot); - verify(collectionReference.queryDelegate.startAtDocument(mockSnapshot)); - }); - - test("endBeforeDocument", () async { - final mockSnapshot = MockDocumentSnapshot(); - collectionReference.endBeforeDocument(mockSnapshot); - verify(collectionReference.queryDelegate.endBeforeDocument(mockSnapshot)); - }); - - test("endAtDocument", () async { - final mockSnapshot = MockDocumentSnapshot(); - collectionReference.endAtDocument(mockSnapshot); - verify(collectionReference.queryDelegate.endAtDocument(mockSnapshot)); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart deleted file mode 100644 index 327b25516a38..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn('chrome') -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:firebase/firestore.dart' as web; -import 'test_common.dart'; - -const _kPath = "test/document"; - -void main() { - group("$DocumentReferenceWeb()", () { - final mockWebDocumentReferences = MockWebDocumentReference(); - DocumentReferenceWeb documentRefernce; - setUp(() { - final mockWebFirestore = mockFirestore(); - when(mockWebFirestore.doc(any)).thenReturn(mockWebDocumentReferences); - documentRefernce = DocumentReferenceWeb( - mockWebFirestore, FirestorePlatform.instance, _kPath.split("/")); - }); - - test("setData", () { - documentRefernce.setData({"test": "test"}); - expect( - verify(mockWebDocumentReferences.set( - any, captureThat(isInstanceOf()))) - .captured - .last - .merge, - isFalse); - documentRefernce.setData({"test": "test"}, merge: true); - expect( - verify(mockWebDocumentReferences.set( - any, captureThat(isInstanceOf()))) - .captured - .last - .merge, - isTrue); - }); - - test("updateData", () { - documentRefernce.updateData({"test": "test"}); - verify(mockWebDocumentReferences.update(data: anyNamed("data"))); - }); - - test("get", () { - final mockWebSnapshot = MockWebDocumentSnapshot(); - when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReferences); - when(mockWebSnapshot.metadata).thenReturn(MockWebSnapshotMetaData()); - when(mockWebDocumentReferences.get()) - .thenAnswer((_) => Future.value(mockWebSnapshot)); - documentRefernce.get(); - verify(mockWebDocumentReferences.get()); - }); - - test("delete", () { - documentRefernce.delete(); - verify(mockWebDocumentReferences.delete()); - }); - - test("snapshots", () { - when(mockWebDocumentReferences.onSnapshot) - .thenAnswer((_) => Stream.empty()); - when(mockWebDocumentReferences.onMetadataChangesSnapshot) - .thenAnswer((_) => Stream.empty()); - documentRefernce.snapshots(); - verify(mockWebDocumentReferences.onSnapshot); - documentRefernce.snapshots(includeMetadataChanges: false); - verify(mockWebDocumentReferences.onSnapshot); - documentRefernce.snapshots(includeMetadataChanges: true); - verify(mockWebDocumentReferences.onMetadataChangesSnapshot); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart deleted file mode 100644 index 566c2ab39938..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn("chrome") -import 'package:firebase/firestore.dart' as web show FieldValue; -import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; -import 'package:cloud_firestore_web/src/field_value_web.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group("$FieldValueFactoryWeb()", () { - final factory = FieldValueFactoryWeb(); - - test("arrayRemove", () { - final FieldValueWeb actual = factory.arrayRemove([]); - expect(actual.data, isInstanceOf()); - }); - - test("arrayUnion", () { - final FieldValueWeb actual = factory.arrayUnion([]); - expect(actual.data, isInstanceOf()); - }); - - test("delete", () { - final FieldValueWeb actual = factory.delete(); - expect(actual.data, isInstanceOf()); - }); - - test("increment", () { - final FieldValueWeb actualInt = factory.increment(1); - expect(actualInt.data, isInstanceOf()); - - final FieldValueWeb actualDouble = factory.increment(1.25); - expect(actualDouble.data, isInstanceOf()); - }); - - test( - "increment throws when attempting to increment something that is not a number", - () { - expect(() { - dynamic malformed = "nope"; - factory.increment(malformed); - }, throwsA(isA())); - }); - - test("serverTimestamp", () { - final FieldValueWeb actual = factory.serverTimestamp(); - expect(actual.data, isInstanceOf()); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart deleted file mode 100644 index 0f853317e7c4..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn("chrome") -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'package:firebase/firestore.dart' as web; -import 'package:cloud_firestore_web/src/query_web.dart'; -import 'test_common.dart'; - -class MockWebQuery extends Mock implements web.Query {} - -class MockFirestoreWeb extends Mock implements FirestoreWeb {} - -class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} - -class MockWebSnapshotMetadata extends Mock implements web.SnapshotMetadata {} - -class MockWebDocumentChange extends Mock implements web.DocumentChange {} - -const _path = "test/query"; - -void main() { - group("$QueryWeb()", () { - final firestore = MockFirestoreWeb(); - final MockWebQuery mockWebQuery = MockWebQuery(); - QueryWeb query; - - setUp(() { - reset(mockWebQuery); - query = QueryWeb(firestore, _path, mockWebQuery); - }); - - test("snapshots", () { - when(mockWebQuery.onSnapshot).thenAnswer((_) => Stream.empty()); - when(mockWebQuery.onSnapshotMetadata).thenAnswer((_) => Stream.empty()); - query.snapshots(); - verify(mockWebQuery.onSnapshot); - query.snapshots(includeMetadataChanges: false); - verify(mockWebQuery.onSnapshot); - query.snapshots(includeMetadataChanges: true); - verify(mockWebQuery.onSnapshotMetadata); - }); - - test("getDocuments", () async { - final mockMetaData = MockWebSnapshotMetadata(); - when(mockMetaData.fromCache).thenReturn(true); - when(mockMetaData.hasPendingWrites).thenReturn(false); - - final mockDocumentReference = MockWebDocumentReference(); - when(mockDocumentReference.path).thenReturn("test/reference"); - - final mockDocumentSnapshot = MockWebDocumentSnapshot(); - when(mockDocumentSnapshot.ref).thenReturn(mockDocumentReference); - when(mockDocumentSnapshot.data()).thenReturn(Map()); - when(mockDocumentSnapshot.metadata).thenReturn(mockMetaData); - - final mockDocumentChange = MockWebDocumentChange(); - when(mockDocumentChange.type).thenReturn("added"); - when(mockDocumentChange.oldIndex).thenReturn(0); - when(mockDocumentChange.newIndex).thenReturn(1); - when(mockDocumentChange.doc).thenReturn(mockDocumentSnapshot); - - final mockQuerySnapshot = MockWebQuerySnapshot(); - when(mockQuerySnapshot.docs).thenReturn([]); - when(mockQuerySnapshot.docChanges()).thenReturn([mockDocumentChange]); - when(mockQuerySnapshot.metadata).thenReturn(mockMetaData); - - when(mockWebQuery.get()) - .thenAnswer((_) => Future.value(mockQuerySnapshot)); - final actual = await query.getDocuments(); - verify(mockWebQuery.get()); - expect( - actual.documentChanges.first.type, equals(DocumentChangeType.added)); - - when(mockDocumentChange.type).thenReturn("modified"); - expect((await query.getDocuments()).documentChanges.first.type, - equals(DocumentChangeType.modified)); - - when(mockDocumentChange.type).thenReturn("removed"); - expect((await query.getDocuments()).documentChanges.first.type, - equals(DocumentChangeType.removed)); - }); - - test("endAt", () { - query.endAt([]); - verify(mockWebQuery.endAt(fieldValues: anyNamed("fieldValues"))); - }); - - test("endAtDocument", () { - final mockDocumentSnapshot = MockDocumentSnapshot(); - when(mockDocumentSnapshot.data).thenReturn({ - 'test': 1, - }); - query.orderBy("test"); - query.endAtDocument(mockDocumentSnapshot); - verify(mockWebQuery.endAt( - fieldValues: argThat(equals([1]), named: "fieldValues"))); - }); - - test("endBefore", () { - query.endBefore([]); - verify(mockWebQuery.endBefore(fieldValues: anyNamed("fieldValues"))); - }); - - test("endBeforeDocument", () { - final mockDocumentSnapshot = MockDocumentSnapshot(); - when(mockDocumentSnapshot.data).thenReturn({ - 'test': 1, - }); - query.orderBy("test"); - query.endBeforeDocument(mockDocumentSnapshot); - verify(mockWebQuery.endBefore( - fieldValues: argThat(equals([1]), named: "fieldValues"))); - }); - - test("startAfter", () { - query.startAfter([]); - verify(mockWebQuery.startAfter(fieldValues: anyNamed("fieldValues"))); - }); - - test("startAfterDocument", () { - final mockDocumentSnapshot = MockDocumentSnapshot(); - when(mockDocumentSnapshot.data).thenReturn({ - 'test': 1, - }); - query.orderBy("test"); - query.startAfterDocument(mockDocumentSnapshot); - verify(mockWebQuery.startAfter( - fieldValues: argThat(equals([1]), named: "fieldValues"))); - }); - - test("startAt", () { - query.startAt([]); - verify(mockWebQuery.startAt(fieldValues: anyNamed("fieldValues"))); - }); - - test("startAtDocument", () { - final mockDocumentSnapshot = MockDocumentSnapshot(); - when(mockDocumentSnapshot.data).thenReturn({ - 'test': 1, - }); - query.orderBy("test"); - query.startAtDocument(mockDocumentSnapshot); - verify(mockWebQuery.startAt( - fieldValues: argThat(equals([1]), named: "fieldValues"))); - }); - - test("limit", () { - query.limit(1); - verify(mockWebQuery.limit(1)); - }); - - test("where", () { - query.where("test", isNull: true); - verify(mockWebQuery.where("test", "==", null)); - - query.where("test", whereIn: [1, 2, 3]); - verify(mockWebQuery.where("test", "in", [1, 2, 3])); - - query.where("test", arrayContainsAny: [1, 2, 3]); - verify(mockWebQuery.where("test", "array-contains-any", [1, 2, 3])); - - query.where("test", arrayContains: [1, 2, 3]); - verify(mockWebQuery.where("test", "array-contains", [1, 2, 3])); - - query.where("test", isGreaterThanOrEqualTo: 1); - verify(mockWebQuery.where("test", ">=", 1)); - - query.where("test", isGreaterThan: 1); - verify(mockWebQuery.where("test", ">", 1)); - - query.where("test", isLessThan: 1); - verify(mockWebQuery.where("test", "<", 1)); - - query.where("test", isLessThanOrEqualTo: 1); - verify(mockWebQuery.where("test", "<=", 1)); - - query.where("test", isEqualTo: 1); - verify(mockWebQuery.where("test", "==", 1)); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart deleted file mode 100644 index 28ebd3587da7..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. 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:js' as js; -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; -import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; -import 'package:firebase_core_web/firebase_core_web.dart'; -import 'package:mockito/mockito.dart'; -import 'package:firebase/firestore.dart' as web; - -import 'package:cloud_firestore_web/src/document_reference_web.dart'; -import 'package:cloud_firestore_web/src/query_web.dart'; - -const kCollectionId = "test"; - -class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} - -class MockWebSnapshotMetaData extends Mock implements web.SnapshotMetadata {} - -class MockFirestoreWeb extends Mock implements web.Firestore {} - -class MockWebTransaction extends Mock implements web.Transaction {} - -class MockWebWriteBatch extends Mock implements web.WriteBatch {} - -class MockDocumentReference extends Mock implements DocumentReferenceWeb {} - -class MockFirestore extends Mock implements FirestoreWeb {} - -class MockWebDocumentReference extends Mock implements web.DocumentReference {} - -class MockWebCollectionReference extends Mock - implements web.CollectionReference {} - -class MockQueryWeb extends Mock implements QueryWeb {} - -class MockDocumentSnapshot extends Mock implements DocumentSnapshotPlatform {} - -web.Firestore mockFirestore() { - final mockFirestoreWeb = MockFirestoreWeb(); - final js.JsObject firebaseMock = js.JsObject.jsify({ - 'firestore': js.allowInterop((_) => mockFirestoreWeb), - 'app': js.allowInterop((String name) { - return js.JsObject.jsify({ - 'name': name, - 'options': {'appId': '123'}, - }); - }) - }); - js.context['firebase'] = firebaseMock; - FirebaseCorePlatform.instance = FirebaseCoreWeb(); - FirestorePlatform.instance = FirestoreWeb(); - return mockFirestoreWeb; -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart deleted file mode 100644 index e7f243862cbe..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn("chrome") -import 'package:cloud_firestore_web/src/transaction_web.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'test_common.dart'; - -void main() { - group("$TransactionWeb()", () { - final mockWebTransaction = MockWebTransaction(); - final mockWebDocumentReference = MockWebDocumentReference(); - final mockDocumentReference = MockDocumentReference(); - final mockFirestore = MockFirestore(); - final transaction = TransactionWeb(mockWebTransaction, mockFirestore); - - setUp(() { - when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); - }); - - test("delete", () async { - await transaction.delete(mockDocumentReference); - verify(mockWebTransaction.delete(mockWebDocumentReference)); - }); - - test("get", () async { - final mockWebSnapshot = MockWebDocumentSnapshot(); - final mockWebDocumentReference = MockWebDocumentReference(); - final mockWebSnapshotMetaData = MockWebSnapshotMetaData(); - when(mockWebSnapshotMetaData.hasPendingWrites).thenReturn(true); - when(mockWebSnapshotMetaData.fromCache).thenReturn(true); - when(mockWebDocumentReference.path).thenReturn("test/path"); - when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReference); - when(mockWebSnapshot.data()).thenReturn(Map()); - when(mockWebSnapshot.metadata).thenReturn(mockWebSnapshotMetaData); - - when(mockWebTransaction.get(any)) - .thenAnswer((_) => Future.value(mockWebSnapshot)); - await transaction.get(mockDocumentReference); - verify(mockWebTransaction.get(any)); - }); - - test("set", () async { - await transaction.set(mockDocumentReference, {}); - verify(mockWebTransaction.set(mockWebDocumentReference, {})); - }); - - test("update", () async { - await transaction.update(mockDocumentReference, {}); - verify(mockWebTransaction.update(mockWebDocumentReference, - data: argThat(equals({}), named: "data"))); - }); - }); -} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart deleted file mode 100644 index b947386de664..000000000000 --- a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -@TestOn("chrome") -import 'package:cloud_firestore_web/src/write_batch_web.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; -import 'test_common.dart'; - -void main() { - group("$WriteBatchWeb()", () { - final mockWebTransaction = MockWebWriteBatch(); - final mockWebDocumentReference = MockWebDocumentReference(); - final mockDocumentReference = MockDocumentReference(); - final transaction = WriteBatchWeb(mockWebTransaction); - - setUp(() { - when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); - }); - - test("delete", () async { - await transaction.delete(mockDocumentReference); - verify(mockWebTransaction.delete(mockWebDocumentReference)); - }); - - test("setData", () async { - await transaction.setData(mockDocumentReference, {}); - verify(mockWebTransaction.set(mockWebDocumentReference, {}, null)); - }); - - test("updateData", () async { - await transaction.updateData(mockDocumentReference, {}); - verify(mockWebTransaction.update(mockWebDocumentReference, - data: argThat(equals({}), named: "data"))); - }); - }); -} From 0e9935667dbb5ab86abc74f74eb49b0043c543c2 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Thu, 6 Feb 2020 09:11:35 +0000 Subject: [PATCH 138/144] Added _web plugin --- .../cloud_firestore_web/CHANGELOG.md | 3 + .../cloud_firestore_web/LICENSE | 27 ++ .../cloud_firestore_web/README.md | 52 +++ .../cloud_firestore_web/android/.gitignore | 8 + .../cloud_firestore_web/android/build.gradle | 33 ++ .../android/gradle.properties | 2 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 3 + .../FirestoreWebPlugin.java | 15 + .../ios/cloud_firestore_web.podspec | 21 ++ .../lib/firestore_web.dart | 96 ++++++ .../lib/src/collection_reference_web.dart | 193 ++++++++++++ .../lib/src/document_reference_web.dart | 66 ++++ .../lib/src/field_value_factory_web.dart | 32 ++ .../lib/src/field_value_web.dart | 16 + .../lib/src/query_web.dart | 298 ++++++++++++++++++ .../lib/src/transaction_web.dart | 65 ++++ .../lib/src/utils/codec_utility.dart | 88 ++++++ .../src/utils/document_reference_utils.dart | 21 ++ .../lib/src/write_batch_web.dart | 51 +++ .../cloud_firestore_web/pubspec.yaml | 35 ++ .../test/codec_utility_test.dart | 194 ++++++++++++ .../test/collection_reference_web_test.dart | 152 +++++++++ .../test/document_reference_web_test.dart | 78 +++++ .../test/field_value_factory_web_test.dart | 52 +++ .../test/query_web_test.dart | 186 +++++++++++ .../cloud_firestore_web/test/test_common.dart | 56 ++++ .../test/transaction_web_test.dart | 56 ++++ .../test/write_batch_web_test.dart | 38 +++ 30 files changed, 1943 insertions(+) create mode 100644 packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md create mode 100644 packages/cloud_firestore/cloud_firestore_web/LICENSE create mode 100644 packages/cloud_firestore/cloud_firestore_web/README.md create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/.gitignore create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/build.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/settings.gradle create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml create mode 100644 packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java create mode 100644 packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/pubspec.yaml create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/test_common.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart create mode 100644 packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md new file mode 100644 index 000000000000..e53776993662 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +- Initial release \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/LICENSE b/packages/cloud_firestore/cloud_firestore_web/LICENSE new file mode 100644 index 000000000000..000b4618d2bd --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2017 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. \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/README.md b/packages/cloud_firestore/cloud_firestore_web/README.md new file mode 100644 index 000000000000..b9d0e93f883d --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/README.md @@ -0,0 +1,52 @@ +# cloud_firestore_web + +The web implementation of [`cloud_firestore`][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 `cloud_firestore` +plugin. + +_(This is only temporary: in the future we hope to make this package +an "endorsed" implementation of `cloud_firestore`, 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: + ... + cloud_firestore: ^0.13.1 + cloud_firestore_web: ^0.1.0 + ... +``` + +### Updating `index.html` + +Due to [this bug in dartdevc][2], you will need to manually add the Firebase +JavaScript files to your `index.html` file. + +In your app directory, edit `web/index.html` to add the line: + +```html + + ... + + + + + + +``` + +### Using the plugin + +Once you have added the `cloud_firebase_web` dependency to your pubspec, +you can use `package:cloud_firebase` as normal. + +[1]: ../cloud_firestore +[2]: https://github.com/dart-lang/sdk/issues/33979 diff --git a/packages/cloud_firestore/cloud_firestore_web/android/.gitignore b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore new file mode 100644 index 000000000000..c6cbe562a427 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/packages/cloud_firestore/cloud_firestore_web/android/build.gradle b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle new file mode 100644 index 000000000000..e3db786e3805 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/build.gradle @@ -0,0 +1,33 @@ +group 'io.flutter.plugins.cloud_firestore_web' +version '1.0' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties new file mode 100644 index 000000000000..3148384dab31 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true \ No newline at end of file diff --git a/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..019065d1d650 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle new file mode 100644 index 000000000000..6bbf9cba49da --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'cloud_firestore_web' diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..ff4f493a984c --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java new file mode 100644 index 000000000000..af02befd488e --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/android/src/main/java/io/flutter/plugins/cloud_firestore_web/FirestoreWebPlugin.java @@ -0,0 +1,15 @@ +package io.flutter.plugins.cloud_firestore_web; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +/** FirebaseAuthWebPlugin */ +public class FirestoreWebPlugin implements FlutterPlugin { + @Override + public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {} + + public static void registerWith(Registrar registrar) {} + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) {} +} diff --git a/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec b/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_web.podspec new file mode 100644 index 000000000000..2e9b05c81076 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/ios/cloud_firestore_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 = 'cloud_firestore_web' + s.version = '0.1.0' + s.summary = 'No-op implementation of cloud_firestore_web web plugin to avoid build issues on iOS' + s.description = <<-DESC + temp fake firebase_auth_web plugin + DESC + s.homepage = 'https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_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/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart new file mode 100644 index 000000000000..0558b9b28597 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart @@ -0,0 +1,96 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firebase.dart' as firebase; +import 'package:firebase/firestore.dart' show Firestore, Settings; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; +import 'package:cloud_firestore_web/src/transaction_web.dart'; +import 'package:cloud_firestore_web/src/write_batch_web.dart'; + +/// Web implementation for [FirestorePlatform] +/// delegates calls to firestore web plugin +class FirestoreWeb extends FirestorePlatform { + /// instance of Firestore from the web plugin + final Firestore _webFirestore; + + /// Called by PluginRegistry to register this plugin for Flutter Web + static void registerWith(Registrar registrar) { + FirestorePlatform.instance = FirestoreWeb(); + } + + /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance + /// If [app] is null then the created instance will use the default [FirebaseApp] + FirestoreWeb({FirebaseApp app}) + : _webFirestore = firebase + .firestore(firebase.app((app ?? FirebaseApp.instance).name)), + super(app: app ?? FirebaseApp.instance) { + FieldValueFactoryPlatform.instance = FieldValueFactoryWeb(); + } + + @override + FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); + + @override + CollectionReferencePlatform collection(String path) { + return CollectionReferenceWeb(this, _webFirestore, path.split('/')); + } + + @override + QueryPlatform collectionGroup(String path) { + return QueryWeb(this, path, _webFirestore.collectionGroup(path), + isCollectionGroup: true); + } + + @override + DocumentReferencePlatform document(String path) => + DocumentReferenceWeb(_webFirestore, this, path.split('/')); + + @override + WriteBatchPlatform batch() => WriteBatchWeb(_webFirestore.batch()); + + @override + Future enablePersistence(bool enable) async { + if (enable) { + await _webFirestore.enablePersistence(); + } + } + + @override + Future settings( + {bool persistenceEnabled, + String host, + bool sslEnabled, + int cacheSizeBytes}) async { + if (host != null && sslEnabled != null) { + _webFirestore.settings(Settings( + cacheSizeBytes: cacheSizeBytes ?? 40000000, + host: host, + ssl: sslEnabled)); + } else { + _webFirestore + .settings(Settings(cacheSizeBytes: cacheSizeBytes ?? 40000000)); + } + if (persistenceEnabled) { + await _webFirestore.enablePersistence(); + } + } + + @override + Future> runTransaction( + TransactionHandler transactionHandler, + {Duration timeout = const Duration(seconds: 5)}) async { + Map result; + await _webFirestore.runTransaction((transaction) async { + result = await transactionHandler(TransactionWeb(transaction, this)); + }).timeout(timeout); + return result is Map ? result : {}; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart new file mode 100644 index 000000000000..a75131e7e2b9 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -0,0 +1,193 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:meta/meta.dart'; + +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; + +/// Web implementation for Firestore [CollectionReferencePlatform] +class CollectionReferenceWeb extends CollectionReferencePlatform { + /// instance of Firestore from the web plugin + final web.Firestore webFirestore; + final FirestorePlatform _firestorePlatform; + final List pathComponents; + // disabling lint as it's only visible for testing + @visibleForTesting + QueryWeb queryDelegate; // ignore: public_member_api_docs + + /// Creates an instance of [CollectionReferenceWeb] which represents path + /// at [pathComponents] and uses implementation of [webFirestore] + CollectionReferenceWeb( + this._firestorePlatform, this.webFirestore, this.pathComponents) + : queryDelegate = QueryWeb( + _firestorePlatform, + pathComponents.join("/"), + webFirestore.collection(pathComponents.join("/")), + ), + super(_firestorePlatform, pathComponents); + + @override + DocumentReferencePlatform parent() { + if (pathComponents.length < 2) { + return null; + } + return DocumentReferenceWeb( + webFirestore, + firestore, + (List.from(pathComponents)..removeLast()), + ); + } + + @override + DocumentReferencePlatform document([String path]) { + List childPath; + if (path == null) { + web.DocumentReference doc = + webFirestore.collection(pathComponents.join('/')).doc(); + childPath = doc.path.split('/'); + } else { + childPath = List.from(pathComponents)..addAll(path.split(('/'))); + } + return DocumentReferenceWeb( + webFirestore, + firestore, + childPath, + ); + } + + @override + Future add(Map data) async { + final DocumentReferencePlatform newDocument = document(); + await newDocument.setData(data); + return newDocument; + } + + @override + Map buildArguments() => queryDelegate.buildArguments(); + + @override + QueryPlatform endAt(List values) { + _resetQueryDelegate(); + return queryDelegate.endAt(values); + } + + @override + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { + _resetQueryDelegate(); + return queryDelegate.endAtDocument(documentSnapshot); + } + + @override + QueryPlatform endBefore(List values) { + _resetQueryDelegate(); + return queryDelegate.endBefore(values); + } + + @override + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { + _resetQueryDelegate(); + return queryDelegate.endBeforeDocument(documentSnapshot); + } + + @override + FirestorePlatform get firestore => _firestorePlatform; + + @override + Future getDocuments({ + Source source = Source.serverAndCache, + }) => + queryDelegate.getDocuments(source: source); + + @override + String get id => pathComponents.isEmpty ? null : pathComponents.last; + + @override + bool get isCollectionGroup => false; + + @override + QueryPlatform limit(int length) { + _resetQueryDelegate(); + return queryDelegate.limit(length); + } + + @override + QueryPlatform orderBy( + field, { + bool descending = false, + }) { + _resetQueryDelegate(); + return queryDelegate.orderBy(field, descending: descending); + } + + @override + Map get parameters => queryDelegate.parameters; + + @override + String get path => pathComponents.join("/"); + + @override + CollectionReferencePlatform reference() => queryDelegate.reference(); + + @override + Stream snapshots({ + bool includeMetadataChanges = false, + }) => + queryDelegate.snapshots(includeMetadataChanges: includeMetadataChanges); + + @override + QueryPlatform startAfter(List values) { + _resetQueryDelegate(); + return queryDelegate.startAfter(values); + } + + @override + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { + _resetQueryDelegate(); + return queryDelegate.startAfterDocument(documentSnapshot); + } + + @override + QueryPlatform startAt(List values) { + _resetQueryDelegate(); + return queryDelegate.startAt(values); + } + + @override + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { + _resetQueryDelegate(); + return queryDelegate.startAtDocument(documentSnapshot); + } + + @override + QueryPlatform where( + field, { + isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { + _resetQueryDelegate(); + return queryDelegate.where(field, + isEqualTo: isEqualTo, + isLessThan: isLessThan, + isLessThanOrEqualTo: isLessThanOrEqualTo, + isGreaterThan: isGreaterThan, + isGreaterThanOrEqualTo: isGreaterThanOrEqualTo, + arrayContains: arrayContains, + arrayContainsAny: arrayContainsAny, + whereIn: whereIn, + isNull: isNull); + } + + void _resetQueryDelegate() => + queryDelegate = queryDelegate.resetQueryDelegate(); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart new file mode 100644 index 000000000000..373ae6f83261 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/document_reference_web.dart @@ -0,0 +1,66 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; + +/// Web implementation for firestore [DocumentReferencePlatform] +class DocumentReferenceWeb extends DocumentReferencePlatform { + /// instance of Firestore from the web plugin + final web.Firestore firestoreWeb; + + /// instance of DocumentReference from the web plugin + final web.DocumentReference delegate; + + /// Creates an instance of [CollectionReferenceWeb] which represents path + /// at [pathComponents] and uses implementation of [firestoreWeb] + DocumentReferenceWeb( + this.firestoreWeb, + FirestorePlatform firestore, + List pathComponents, + ) : delegate = firestoreWeb.doc(pathComponents.join("/")), + super(firestore, pathComponents); + + @override + Future setData( + Map data, { + bool merge = false, + }) => + delegate.set( + CodecUtility.encodeMapData(data), + web.SetOptions(merge: merge), + ); + + @override + Future updateData(Map data) => + delegate.update(data: CodecUtility.encodeMapData(data)); + + @override + Future get({ + Source source = Source.serverAndCache, + }) async { + return fromWebDocumentSnapshotToPlatformDocumentSnapshot( + await delegate.get(), this.firestore); + } + + @override + Future delete() => delegate.delete(); + + @override + Stream snapshots({ + bool includeMetadataChanges = false, + }) { + Stream querySnapshots = delegate.onSnapshot; + if (includeMetadataChanges) { + querySnapshots = delegate.onMetadataChangesSnapshot; + } + return querySnapshots.map((webSnapshot) => + fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this.firestore)); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart new file mode 100644 index 000000000000..cfae0922dfa1 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_factory_web.dart @@ -0,0 +1,32 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:js/js_util.dart'; + +import 'package:cloud_firestore_web/src/field_value_web.dart'; + +/// An implementation of [FieldValueFactoryPlatform] which builds [FieldValuePlatform] +/// instance that is [jsify] friendly +class FieldValueFactoryWeb extends FieldValueFactoryPlatform { + @override + FieldValuePlatform arrayRemove(List elements) => + FieldValueWeb(web.FieldValue.arrayRemove(elements)); + + @override + FieldValuePlatform arrayUnion(List elements) => + FieldValueWeb(web.FieldValue.arrayUnion(elements)); + + @override + FieldValuePlatform delete() => FieldValueWeb(web.FieldValue.delete()); + + @override + FieldValuePlatform increment(num value) => + FieldValueWeb(web.FieldValue.increment(value)); + + @override + FieldValuePlatform serverTimestamp() => + FieldValueWeb(web.FieldValue.serverTimestamp()); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart new file mode 100644 index 000000000000..c3e7e5c38881 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -0,0 +1,16 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +/// Implementation of [FieldValuePlatform] that is compatible with +/// firestore web plugin +class FieldValueWeb extends FieldValuePlatform { + /// The js-interop delegate for this [FieldValuePlatform] + web.FieldValue data; + + /// Constructor. + FieldValueWeb(this.data) : super(); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart new file mode 100644 index 000000000000..bd677246ab0a --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -0,0 +1,298 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; + +/// Web implementation for firestore [QueryPlatform] +class QueryWeb extends QueryPlatform { + final web.Query _webQuery; + final FirestorePlatform _firestore; + final bool _isCollectionGroup; + final String _path; + final List _orderByKeys; + static const _kChangeTypeAdded = "added"; + static const _kChangeTypeModified = "modified"; + static const _kChangeTypeRemoved = "removed"; + + /// Builds an instance of [QueryWeb] using [_path] & [_webQuery] + /// to delegate queries to underlying firestore web plugin + QueryWeb( + this._firestore, + this._path, + this._webQuery, { + bool isCollectionGroup, + List orderByKeys, + }) : this._isCollectionGroup = isCollectionGroup ?? false, + this._orderByKeys = orderByKeys ?? [], + super( + firestore: _firestore, + pathComponents: _path.split('/'), + isCollectionGroup: isCollectionGroup, + ); + + @override + Stream snapshots({ + bool includeMetadataChanges = false, + }) { + assert(_webQuery != null); + Stream querySnapshots = _webQuery.onSnapshot; + if (includeMetadataChanges) { + querySnapshots = _webQuery.onSnapshotMetadata; + } + return querySnapshots.map(_webQuerySnapshotToQuerySnapshot); + } + + @override + Future getDocuments({ + Source source = Source.serverAndCache, + }) async { + assert(_webQuery != null); + return _webQuerySnapshotToQuerySnapshot(await _webQuery.get()); + } + + @override + Map buildArguments() => Map(); + + @override + QueryPlatform endAt(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery != null ? _webQuery.endAt(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup, + ); + + @override + QueryPlatform endAtDocument(DocumentSnapshotPlatform documentSnapshot) { + assert(_webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + _webQuery.endAt( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + isCollectionGroup: _isCollectionGroup); + } + + @override + QueryPlatform endBefore(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery != null ? _webQuery.endBefore(fieldValues: values) : null, + isCollectionGroup: _isCollectionGroup, + ); + + @override + QueryPlatform endBeforeDocument(DocumentSnapshotPlatform documentSnapshot) { + assert(_webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + _webQuery.endBefore( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + isCollectionGroup: _isCollectionGroup); + } + + @override + FirestorePlatform get firestore => _firestore; + + @override + bool get isCollectionGroup => _isCollectionGroup; + + @override + QueryPlatform limit(int length) => QueryWeb( + this._firestore, + this._path, + _webQuery != null ? _webQuery.limit(length) : null, + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); + + @override + QueryPlatform orderBy( + field, { + bool descending = false, + }) { + dynamic usableField = field; + if (field == FieldPath.documentId) { + usableField = web.FieldPath.documentId(); + } + return QueryWeb( + this._firestore, + this._path, + _webQuery.orderBy(usableField, descending ? "desc" : "asc"), + orderByKeys: _orderByKeys..add(usableField), + isCollectionGroup: _isCollectionGroup, + ); + } + + @override + String get path => this._path; + + @override + List get pathComponents => this._path.split("/"); + + @override + CollectionReferencePlatform reference() => firestore.collection(_path); + + @override + QueryPlatform startAfter(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery.startAfter(fieldValues: values), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); + + @override + QueryPlatform startAfterDocument(DocumentSnapshotPlatform documentSnapshot) { + assert(_webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + _webQuery.startAfter( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList()), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup); + } + + @override + QueryPlatform startAt(List values) => QueryWeb( + this._firestore, + this._path, + _webQuery.startAt(fieldValues: values), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); + + @override + QueryPlatform startAtDocument(DocumentSnapshotPlatform documentSnapshot) { + assert(_webQuery != null && _orderByKeys.isNotEmpty); + return QueryWeb( + this._firestore, + this._path, + _webQuery.startAt( + fieldValues: + _orderByKeys.map((key) => documentSnapshot.data[key]).toList(), + ), + orderByKeys: _orderByKeys, + isCollectionGroup: _isCollectionGroup, + ); + } + + @override + QueryPlatform where( + field, { + isEqualTo, + isLessThan, + isLessThanOrEqualTo, + isGreaterThan, + isGreaterThanOrEqualTo, + arrayContains, + List arrayContainsAny, + List whereIn, + bool isNull, + }) { + assert(field is String || field is FieldPath, + 'Supported [field] types are [String] and [FieldPath].'); + assert(_webQuery != null); + dynamic usableField = field; + if (field == FieldPath.documentId) { + usableField = web.FieldPath.documentId(); + } + web.Query query = _webQuery; + + if (isEqualTo != null) { + query = query.where(usableField, "==", isEqualTo); + } + if (isLessThan != null) { + query = query.where(usableField, "<", isLessThan); + } + if (isLessThanOrEqualTo != null) { + query = query.where(usableField, "<=", isLessThanOrEqualTo); + } + if (isGreaterThan != null) { + query = query.where(usableField, ">", isGreaterThan); + } + if (isGreaterThanOrEqualTo != null) { + query = query.where(usableField, ">=", isGreaterThanOrEqualTo); + } + if (arrayContains != null) { + query = query.where(usableField, "array-contains", arrayContains); + } + if (arrayContainsAny != null) { + assert(arrayContainsAny.length <= 10, + "array contains can have maximum of 10 items"); + query = query.where(usableField, "array-contains-any", arrayContainsAny); + } + if (whereIn != null) { + assert( + whereIn.length <= 10, "array contains can have maximum of 10 items"); + query = query.where(usableField, "in", whereIn); + } + if (isNull != null) { + assert( + isNull, + 'isNull can only be set to true. ' + 'Use isEqualTo to filter on non-null values.'); + query = query.where(usableField, "==", null); + } + return QueryWeb(this._firestore, this._path, query, + orderByKeys: _orderByKeys, isCollectionGroup: _isCollectionGroup); + } + + QuerySnapshotPlatform _webQuerySnapshotToQuerySnapshot( + web.QuerySnapshot webSnapshot, + ) { + return QuerySnapshotPlatform( + webSnapshot.docs + .map((webSnapshot) => + fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this._firestore)) + .toList(), + webSnapshot.docChanges().map(_webChangeToChange).toList(), + _webMetadataToMetada(webSnapshot.metadata)); + } + + DocumentChangePlatform _webChangeToChange(web.DocumentChange webChange) { + return DocumentChangePlatform( + _fromString(webChange.type), + webChange.oldIndex, + webChange.newIndex, + fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webChange.doc, this._firestore)); + } + + DocumentChangeType _fromString(String item) { + switch (item.toLowerCase()) { + case _kChangeTypeAdded: + return DocumentChangeType.added; + case _kChangeTypeModified: + return DocumentChangeType.modified; + case _kChangeTypeRemoved: + return DocumentChangeType.removed; + default: + throw ArgumentError("Invalid type"); + } + } + + SnapshotMetadataPlatform _webMetadataToMetada( + web.SnapshotMetadata webMetadata) { + return SnapshotMetadataPlatform( + webMetadata.hasPendingWrites, + webMetadata.fromCache, + ); + } + + @override + Map get parameters => Map(); + + /// Returns a clean clone of this QueryWeb. + QueryWeb resetQueryDelegate() => + QueryWeb(firestore, pathComponents.join("/"), _webQuery); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart new file mode 100644 index 000000000000..e93e0c8ef715 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/transaction_web.dart @@ -0,0 +1,65 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; + +/// A web specific for [Transaction] +class TransactionWeb extends TransactionPlatform { + final web.Transaction _webTransaction; + @override + FirestorePlatform firestore; + + /// Constructor. + TransactionWeb(this._webTransaction, this.firestore) : super(firestore); + + @override + Future delete(DocumentReferencePlatform documentReference) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction + .delete((documentReference as DocumentReferenceWeb).delegate); + } + + @override + Future get( + DocumentReferencePlatform documentReference, + ) async { + assert(documentReference is DocumentReferenceWeb); + final webSnapshot = await _webTransaction + .get((documentReference as DocumentReferenceWeb).delegate); + return fromWebDocumentSnapshotToPlatformDocumentSnapshot( + webSnapshot, this.firestore); + } + + @override + Future set( + DocumentReferencePlatform documentReference, + Map data, + ) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction.set( + (documentReference as DocumentReferenceWeb).delegate, + CodecUtility.encodeMapData(data)); + } + + @override + Future update( + DocumentReferencePlatform documentReference, + Map data, + ) async { + assert(documentReference is DocumentReferenceWeb); + await _webTransaction.update( + (documentReference as DocumentReferenceWeb).delegate, + data: CodecUtility.encodeMapData(data)); + } + + @override + Future finish() { + return Future.value(); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart new file mode 100644 index 000000000000..1d6145c5c6c1 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -0,0 +1,88 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/field_value_web.dart'; + +/// Class containing static utility methods to encode/decode firestore data. +class CodecUtility { + /// Encodes a Map of values from their proper types to a serialized version. + static Map encodeMapData(Map data) { + if (data == null) { + return null; + } + Map output = Map.from(data); + output.updateAll((key, value) => valueEncode(value)); + return output; + } + + /// Encodes an Array of values from their proper types to a serialized version. + static List encodeArrayData(List data) { + if (data == null) { + return null; + } + return List.from(data).map(valueEncode).toList(); + } + + /// Encodes a value from its proper type to a serialized version. + static dynamic valueEncode(dynamic value) { + if (value is FieldValuePlatform) { + FieldValueWeb delegate = FieldValuePlatform.getDelegate(value); + return delegate.data; + } else if (value is Timestamp) { + return value.toDate(); + } else if (value is GeoPoint) { + return web.GeoPoint(value.latitude, value.longitude); + } else if (value is Blob) { + return web.Blob.fromUint8Array(value.bytes); + } else if (value is DocumentReferenceWeb) { + return value.delegate; + } else if (value is Map) { + return encodeMapData(value); + } else if (value is List) { + return encodeArrayData(value); + } + return value; + } + + /// Decodes the values on an incoming Map to their proper types. + static Map decodeMapData(Map data) { + if (data == null) { + return null; + } + Map output = Map.from(data); + output.updateAll((key, value) => valueDecode(value)); + return output; + } + + /// Decodes the values on an incoming Array to their proper types. + static List decodeArrayData(List data) { + if (data == null) { + return null; + } + return List.from(data).map(valueDecode).toList(); + } + + /// Decodes an incoming value to its proper type. + static dynamic valueDecode(dynamic value) { + if (value is web.GeoPoint) { + return GeoPoint(value.latitude, value.longitude); + } else if (value is DateTime) { + return Timestamp.fromDate(value); + } else if (value is web.Blob) { + return Blob(value.toUint8Array()); + } else if (value is web.DocumentReference) { + return (FirestorePlatform.instance as FirestoreWeb).document(value.path); + } else if (value is Map) { + return decodeMapData(value); + } else if (value is List) { + return decodeArrayData(value); + } + return value; + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart new file mode 100644 index 000000000000..e723c0025375 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/document_reference_utils.dart @@ -0,0 +1,21 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; + +/// Builds [DocumentSnapshotPlatform] instance form web snapshot instance +DocumentSnapshotPlatform fromWebDocumentSnapshotToPlatformDocumentSnapshot( + web.DocumentSnapshot webSnapshot, FirestorePlatform firestore) { + return DocumentSnapshotPlatform( + webSnapshot.ref.path, + CodecUtility.decodeMapData(webSnapshot.data()), + SnapshotMetadataPlatform( + webSnapshot.metadata.hasPendingWrites, + webSnapshot.metadata.fromCache, + ), + firestore); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart new file mode 100644 index 000000000000..7d76b20b8fda --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/write_batch_web.dart @@ -0,0 +1,51 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; + +/// A web specific for [WriteBatch] +class WriteBatchWeb extends WriteBatchPlatform { + final web.WriteBatch _delegate; + + /// Constructor. + WriteBatchWeb(this._delegate); + + @override + Future commit() async { + await _delegate.commit(); + } + + @override + void delete(DocumentReferencePlatform document) { + assert(document is DocumentReferenceWeb); + _delegate.delete((document as DocumentReferenceWeb).delegate); + } + + @override + void setData( + DocumentReferencePlatform document, + Map data, { + bool merge = false, + }) { + assert(document is DocumentReferenceWeb); + _delegate.set( + (document as DocumentReferenceWeb).delegate, + CodecUtility.encodeMapData(data), + merge ? web.SetOptions(merge: merge) : null); + } + + @override + void updateData( + DocumentReferencePlatform document, + Map data, + ) { + assert(document is DocumentReferenceWeb); + _delegate.update((document as DocumentReferenceWeb).delegate, + data: CodecUtility.encodeMapData(data)); + } +} diff --git a/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml new file mode 100644 index 000000000000..1e7fa80cf26b --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/pubspec.yaml @@ -0,0 +1,35 @@ +name: cloud_firestore_web +description: The web implementation of cloud_firestore +homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore_web +version: 0.1.0 + +flutter: + plugin: + platforms: + web: + pluginClass: FirestoreWeb + fileName: firestore_web.dart + +dependencies: + flutter: + sdk: flutter + flutter_web_plugins: + sdk: flutter + firebase: ^7.0.0 + http_parser: ^3.1.3 + meta: ^1.1.7 + firebase_core: ^0.4.3+1 + cloud_firestore_platform_interface: "^1.0.0" + js: ^0.6.1 + +dev_dependencies: + flutter_test: + sdk: flutter + firebase_core_platform_interface: ^1.0.0 + firebase_core_web: ^0.1.1 + mockito: ^4.1.1 + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4 <2.0.0" + diff --git a/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart new file mode 100644 index 000000000000..ea4c1783cb4b --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/codec_utility_test.dart @@ -0,0 +1,194 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn("chrome") +import 'dart:typed_data'; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'dart:js' as js; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; + +class MockGeoPoint extends Mock implements GeoPoint {} + +class MockBlob extends Mock implements Blob {} + +class MockDocumentReferenceWeb extends Mock implements DocumentReferenceWeb {} + +class MockWebGeoPoint extends Mock implements web.GeoPoint {} + +class MockWebBlob extends Mock implements web.Blob {} + +void main() { + group("$CodecUtility()", () { + final FieldValuePlatform mockFieldValue = + FieldValuePlatform(FieldValueFactoryWeb().increment(2.0)); + + setUp(() { + js.context['firebase'] = js.JsObject.jsify({ + 'firestore': js.JsObject.jsify({ + 'GeoPoint': + js.allowInterop((latitude, longitude) => MockWebGeoPoint()), + 'Blob': js.JsObject.jsify({ + 'fromUint8Array': js.allowInterop((_) => MockWebBlob()) + }) + }) + }); + }); + + test("encodeMapData", () { + expect(CodecUtility.encodeMapData(null), isNull); + //FieldValuePlatform + CodecUtility.encodeMapData({'test': mockFieldValue}); + + final timeStamp = Timestamp.now(); + final result = CodecUtility.encodeMapData({'test': timeStamp}); + expect(result['test'], isInstanceOf()); + + //GeoPoint + final mockGeoPoint = MockGeoPoint(); + CodecUtility.encodeMapData({'test': mockGeoPoint}); + verify(mockGeoPoint.latitude); + verify(mockGeoPoint.longitude); + + //Blob + final mockBlob = MockBlob(); + CodecUtility.encodeMapData({'test': mockBlob}); + verify(mockBlob.bytes); + + //DocumentReferenceWeb + final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); + CodecUtility.encodeMapData({'test': mockDocumentReferenceWeb}); + verify(mockDocumentReferenceWeb.delegate); + + //Map + reset(mockDocumentReferenceWeb); + CodecUtility.encodeMapData({ + 'test': {'test2': mockDocumentReferenceWeb} + }); + verify(mockDocumentReferenceWeb.delegate); + + //List + reset(mockDocumentReferenceWeb); + CodecUtility.encodeMapData({ + 'test': [mockDocumentReferenceWeb] + }); + verify(mockDocumentReferenceWeb.delegate); + }); + + test("encodeArrayData", () { + expect(CodecUtility.encodeArrayData(null), isNull); + + //FieldValuePlatform + CodecUtility.encodeArrayData([mockFieldValue]); + + final timeStamp = Timestamp.now(); + final result = CodecUtility.encodeArrayData([timeStamp]); + expect(result.first, isInstanceOf()); + + //GeoPoint + final mockGeoPoint = MockGeoPoint(); + CodecUtility.encodeArrayData([mockGeoPoint]); + verify(mockGeoPoint.latitude); + verify(mockGeoPoint.longitude); + + //Blob + final mockBlob = MockBlob(); + CodecUtility.encodeArrayData([mockBlob]); + verify(mockBlob.bytes); + + //DocumentReferenceWeb + final mockDocumentReferenceWeb = MockDocumentReferenceWeb(); + CodecUtility.encodeArrayData([mockDocumentReferenceWeb]); + verify(mockDocumentReferenceWeb.delegate); + + //Map + reset(mockDocumentReferenceWeb); + CodecUtility.encodeArrayData([ + {'test2': mockDocumentReferenceWeb} + ]); + verify(mockDocumentReferenceWeb.delegate); + + //List + reset(mockDocumentReferenceWeb); + CodecUtility.encodeArrayData([ + [mockDocumentReferenceWeb] + ]); + verify(mockDocumentReferenceWeb.delegate); + }); + + test("decodeMapData", () { + expect(CodecUtility.decodeMapData(null), isNull); + + //Blob + final mockWebBlob = MockWebBlob(); + when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); + expect(CodecUtility.decodeMapData({'test': mockWebBlob})['test'], + isInstanceOf()); + verify(mockWebBlob.toUint8Array()); + + final date = DateTime.now(); + expect(CodecUtility.decodeMapData({'test': date})['test'], + isInstanceOf()); + + //GeoPoint + final mockWebGeoPoint = MockWebGeoPoint(); + expect(CodecUtility.decodeMapData({'test': mockWebGeoPoint})['test'], + isInstanceOf()); + + //Map + expect( + CodecUtility.decodeMapData({ + 'test': {'test1': mockWebGeoPoint} + })['test']['test1'], + isInstanceOf()); + + //List + expect( + CodecUtility.decodeMapData({ + 'test': [mockWebGeoPoint] + })['test'] + .first, + isInstanceOf()); + }); + + test("decodeArrayData", () { + expect(CodecUtility.decodeArrayData(null), isNull); + + //Blob + final mockWebBlob = MockWebBlob(); + when(mockWebBlob.toUint8Array()).thenReturn(Uint8List(0)); + expect(CodecUtility.decodeArrayData([mockWebBlob]).first, + isInstanceOf()); + verify(mockWebBlob.toUint8Array()); + + final date = DateTime.now(); + expect(CodecUtility.decodeArrayData([date]).first, + isInstanceOf()); + + //GeoPoint + final mockWebGeoPoint = MockWebGeoPoint(); + expect(CodecUtility.decodeArrayData([mockWebGeoPoint]).first, + isInstanceOf()); + + //Map + expect( + CodecUtility.decodeArrayData([ + {'test1': mockWebGeoPoint} + ]).first['test1'], + isInstanceOf()); + + //List + expect( + CodecUtility.decodeArrayData([ + [mockWebGeoPoint] + ]).first.first, + isInstanceOf()); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart new file mode 100644 index 000000000000..6b2c8c19973a --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/collection_reference_web_test.dart @@ -0,0 +1,152 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn('chrome') +import 'dart:js' as js; + +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/src/collection_reference_web.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'test_common.dart'; + +void main() { + group("$CollectionReferenceWeb()", () { + final mockDocumentReference = MockWebDocumentReference(); + final mockCollectionReference = MockWebCollectionReference(); + final anotherMockDocumentReference = MockWebDocumentReference(); + CollectionReferenceWeb collectionReference; + setUp(() { + final mockFirestoreWeb = mockFirestore(); + collectionReference = CollectionReferenceWeb(FirestorePlatform.instance, + js.context['firebase']['firestore'](""), [kCollectionId]); + collectionReference.queryDelegate = MockQueryWeb(); + when(mockFirestoreWeb.doc(any)).thenReturn(mockDocumentReference); + + // Used for document creation... + when(mockFirestoreWeb.collection(any)) + .thenReturn(mockCollectionReference); + when(mockCollectionReference.doc(any)).thenReturn(mockDocumentReference); + when(mockCollectionReference.doc(null)) + .thenReturn(anotherMockDocumentReference); + + when(anotherMockDocumentReference.path).thenReturn("test/asdf"); + + when(collectionReference.queryDelegate.resetQueryDelegate()) + .thenReturn(collectionReference.queryDelegate); + }); + + test("parent", () { + expect(collectionReference.parent(), isNull); + expect( + CollectionReferenceWeb( + FirestorePlatform.instance, + js.context['firebase']['firestore'](""), + [kCollectionId, kCollectionId, kCollectionId]).parent(), + isInstanceOf()); + }); + + test("document", () { + final newDocument = collectionReference.document(); + expect(newDocument.path.split("/").length, + collectionReference.pathComponents.length + 1); + final newDocumentWithPath = collectionReference.document("test1"); + expect(newDocumentWithPath.path, + equals("${collectionReference.path}/test1")); + }); + + test("add", () async { + expect(await collectionReference.add({}), + isInstanceOf()); + }); + + test("buildArguments", () async { + collectionReference.buildArguments(); + verify(collectionReference.queryDelegate.buildArguments()); + }); + + test("getDocuments", () async { + await collectionReference.getDocuments(); + verify(collectionReference.queryDelegate.getDocuments()); + }); + + test("reference", () async { + collectionReference.reference(); + verify(collectionReference.queryDelegate.reference()); + }); + + test("snapshots", () async { + collectionReference.snapshots(includeMetadataChanges: true); + verify(collectionReference.queryDelegate + .snapshots(includeMetadataChanges: true)); + collectionReference.snapshots(includeMetadataChanges: false); + verify(collectionReference.queryDelegate + .snapshots(includeMetadataChanges: false)); + }); + + test("where", () async { + collectionReference.where("test"); + verify(collectionReference.queryDelegate.where("test")); + }); + + test("startAt", () async { + collectionReference.startAt([]); + verify(collectionReference.queryDelegate.startAt([])); + }); + + test("startAfter", () async { + collectionReference.startAfter([]); + verify(collectionReference.queryDelegate.startAfter([])); + }); + + test("endBefore", () async { + collectionReference.endBefore([]); + verify(collectionReference.queryDelegate.endBefore([])); + }); + + test("endAt", () async { + collectionReference.endAt([]); + verify(collectionReference.queryDelegate.endAt([])); + }); + + test("limit", () async { + collectionReference.limit(1); + verify(collectionReference.queryDelegate.limit(1)); + }); + + test("orderBy", () async { + collectionReference.orderBy("test"); + verify(collectionReference.queryDelegate.orderBy("test")); + collectionReference.orderBy("test", descending: true); + verify( + collectionReference.queryDelegate.orderBy("test", descending: true)); + }); + + test("startAfterDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.startAfterDocument(mockSnapshot); + verify( + collectionReference.queryDelegate.startAfterDocument(mockSnapshot)); + }); + + test("startAtDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.startAtDocument(mockSnapshot); + verify(collectionReference.queryDelegate.startAtDocument(mockSnapshot)); + }); + + test("endBeforeDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.endBeforeDocument(mockSnapshot); + verify(collectionReference.queryDelegate.endBeforeDocument(mockSnapshot)); + }); + + test("endAtDocument", () async { + final mockSnapshot = MockDocumentSnapshot(); + collectionReference.endAtDocument(mockSnapshot); + verify(collectionReference.queryDelegate.endAtDocument(mockSnapshot)); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart new file mode 100644 index 000000000000..327b25516a38 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/document_reference_web_test.dart @@ -0,0 +1,78 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn('chrome') +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; +import 'test_common.dart'; + +const _kPath = "test/document"; + +void main() { + group("$DocumentReferenceWeb()", () { + final mockWebDocumentReferences = MockWebDocumentReference(); + DocumentReferenceWeb documentRefernce; + setUp(() { + final mockWebFirestore = mockFirestore(); + when(mockWebFirestore.doc(any)).thenReturn(mockWebDocumentReferences); + documentRefernce = DocumentReferenceWeb( + mockWebFirestore, FirestorePlatform.instance, _kPath.split("/")); + }); + + test("setData", () { + documentRefernce.setData({"test": "test"}); + expect( + verify(mockWebDocumentReferences.set( + any, captureThat(isInstanceOf()))) + .captured + .last + .merge, + isFalse); + documentRefernce.setData({"test": "test"}, merge: true); + expect( + verify(mockWebDocumentReferences.set( + any, captureThat(isInstanceOf()))) + .captured + .last + .merge, + isTrue); + }); + + test("updateData", () { + documentRefernce.updateData({"test": "test"}); + verify(mockWebDocumentReferences.update(data: anyNamed("data"))); + }); + + test("get", () { + final mockWebSnapshot = MockWebDocumentSnapshot(); + when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReferences); + when(mockWebSnapshot.metadata).thenReturn(MockWebSnapshotMetaData()); + when(mockWebDocumentReferences.get()) + .thenAnswer((_) => Future.value(mockWebSnapshot)); + documentRefernce.get(); + verify(mockWebDocumentReferences.get()); + }); + + test("delete", () { + documentRefernce.delete(); + verify(mockWebDocumentReferences.delete()); + }); + + test("snapshots", () { + when(mockWebDocumentReferences.onSnapshot) + .thenAnswer((_) => Stream.empty()); + when(mockWebDocumentReferences.onMetadataChangesSnapshot) + .thenAnswer((_) => Stream.empty()); + documentRefernce.snapshots(); + verify(mockWebDocumentReferences.onSnapshot); + documentRefernce.snapshots(includeMetadataChanges: false); + verify(mockWebDocumentReferences.onSnapshot); + documentRefernce.snapshots(includeMetadataChanges: true); + verify(mockWebDocumentReferences.onMetadataChangesSnapshot); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart new file mode 100644 index 000000000000..566c2ab39938 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/field_value_factory_web_test.dart @@ -0,0 +1,52 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn("chrome") +import 'package:firebase/firestore.dart' as web show FieldValue; +import 'package:cloud_firestore_web/src/field_value_factory_web.dart'; +import 'package:cloud_firestore_web/src/field_value_web.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group("$FieldValueFactoryWeb()", () { + final factory = FieldValueFactoryWeb(); + + test("arrayRemove", () { + final FieldValueWeb actual = factory.arrayRemove([]); + expect(actual.data, isInstanceOf()); + }); + + test("arrayUnion", () { + final FieldValueWeb actual = factory.arrayUnion([]); + expect(actual.data, isInstanceOf()); + }); + + test("delete", () { + final FieldValueWeb actual = factory.delete(); + expect(actual.data, isInstanceOf()); + }); + + test("increment", () { + final FieldValueWeb actualInt = factory.increment(1); + expect(actualInt.data, isInstanceOf()); + + final FieldValueWeb actualDouble = factory.increment(1.25); + expect(actualDouble.data, isInstanceOf()); + }); + + test( + "increment throws when attempting to increment something that is not a number", + () { + expect(() { + dynamic malformed = "nope"; + factory.increment(malformed); + }, throwsA(isA())); + }); + + test("serverTimestamp", () { + final FieldValueWeb actual = factory.serverTimestamp(); + expect(actual.data, isInstanceOf()); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart new file mode 100644 index 000000000000..0f853317e7c4 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -0,0 +1,186 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn("chrome") +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; +import 'package:cloud_firestore_web/src/query_web.dart'; +import 'test_common.dart'; + +class MockWebQuery extends Mock implements web.Query {} + +class MockFirestoreWeb extends Mock implements FirestoreWeb {} + +class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} + +class MockWebSnapshotMetadata extends Mock implements web.SnapshotMetadata {} + +class MockWebDocumentChange extends Mock implements web.DocumentChange {} + +const _path = "test/query"; + +void main() { + group("$QueryWeb()", () { + final firestore = MockFirestoreWeb(); + final MockWebQuery mockWebQuery = MockWebQuery(); + QueryWeb query; + + setUp(() { + reset(mockWebQuery); + query = QueryWeb(firestore, _path, mockWebQuery); + }); + + test("snapshots", () { + when(mockWebQuery.onSnapshot).thenAnswer((_) => Stream.empty()); + when(mockWebQuery.onSnapshotMetadata).thenAnswer((_) => Stream.empty()); + query.snapshots(); + verify(mockWebQuery.onSnapshot); + query.snapshots(includeMetadataChanges: false); + verify(mockWebQuery.onSnapshot); + query.snapshots(includeMetadataChanges: true); + verify(mockWebQuery.onSnapshotMetadata); + }); + + test("getDocuments", () async { + final mockMetaData = MockWebSnapshotMetadata(); + when(mockMetaData.fromCache).thenReturn(true); + when(mockMetaData.hasPendingWrites).thenReturn(false); + + final mockDocumentReference = MockWebDocumentReference(); + when(mockDocumentReference.path).thenReturn("test/reference"); + + final mockDocumentSnapshot = MockWebDocumentSnapshot(); + when(mockDocumentSnapshot.ref).thenReturn(mockDocumentReference); + when(mockDocumentSnapshot.data()).thenReturn(Map()); + when(mockDocumentSnapshot.metadata).thenReturn(mockMetaData); + + final mockDocumentChange = MockWebDocumentChange(); + when(mockDocumentChange.type).thenReturn("added"); + when(mockDocumentChange.oldIndex).thenReturn(0); + when(mockDocumentChange.newIndex).thenReturn(1); + when(mockDocumentChange.doc).thenReturn(mockDocumentSnapshot); + + final mockQuerySnapshot = MockWebQuerySnapshot(); + when(mockQuerySnapshot.docs).thenReturn([]); + when(mockQuerySnapshot.docChanges()).thenReturn([mockDocumentChange]); + when(mockQuerySnapshot.metadata).thenReturn(mockMetaData); + + when(mockWebQuery.get()) + .thenAnswer((_) => Future.value(mockQuerySnapshot)); + final actual = await query.getDocuments(); + verify(mockWebQuery.get()); + expect( + actual.documentChanges.first.type, equals(DocumentChangeType.added)); + + when(mockDocumentChange.type).thenReturn("modified"); + expect((await query.getDocuments()).documentChanges.first.type, + equals(DocumentChangeType.modified)); + + when(mockDocumentChange.type).thenReturn("removed"); + expect((await query.getDocuments()).documentChanges.first.type, + equals(DocumentChangeType.removed)); + }); + + test("endAt", () { + query.endAt([]); + verify(mockWebQuery.endAt(fieldValues: anyNamed("fieldValues"))); + }); + + test("endAtDocument", () { + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test': 1, + }); + query.orderBy("test"); + query.endAtDocument(mockDocumentSnapshot); + verify(mockWebQuery.endAt( + fieldValues: argThat(equals([1]), named: "fieldValues"))); + }); + + test("endBefore", () { + query.endBefore([]); + verify(mockWebQuery.endBefore(fieldValues: anyNamed("fieldValues"))); + }); + + test("endBeforeDocument", () { + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test': 1, + }); + query.orderBy("test"); + query.endBeforeDocument(mockDocumentSnapshot); + verify(mockWebQuery.endBefore( + fieldValues: argThat(equals([1]), named: "fieldValues"))); + }); + + test("startAfter", () { + query.startAfter([]); + verify(mockWebQuery.startAfter(fieldValues: anyNamed("fieldValues"))); + }); + + test("startAfterDocument", () { + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test': 1, + }); + query.orderBy("test"); + query.startAfterDocument(mockDocumentSnapshot); + verify(mockWebQuery.startAfter( + fieldValues: argThat(equals([1]), named: "fieldValues"))); + }); + + test("startAt", () { + query.startAt([]); + verify(mockWebQuery.startAt(fieldValues: anyNamed("fieldValues"))); + }); + + test("startAtDocument", () { + final mockDocumentSnapshot = MockDocumentSnapshot(); + when(mockDocumentSnapshot.data).thenReturn({ + 'test': 1, + }); + query.orderBy("test"); + query.startAtDocument(mockDocumentSnapshot); + verify(mockWebQuery.startAt( + fieldValues: argThat(equals([1]), named: "fieldValues"))); + }); + + test("limit", () { + query.limit(1); + verify(mockWebQuery.limit(1)); + }); + + test("where", () { + query.where("test", isNull: true); + verify(mockWebQuery.where("test", "==", null)); + + query.where("test", whereIn: [1, 2, 3]); + verify(mockWebQuery.where("test", "in", [1, 2, 3])); + + query.where("test", arrayContainsAny: [1, 2, 3]); + verify(mockWebQuery.where("test", "array-contains-any", [1, 2, 3])); + + query.where("test", arrayContains: [1, 2, 3]); + verify(mockWebQuery.where("test", "array-contains", [1, 2, 3])); + + query.where("test", isGreaterThanOrEqualTo: 1); + verify(mockWebQuery.where("test", ">=", 1)); + + query.where("test", isGreaterThan: 1); + verify(mockWebQuery.where("test", ">", 1)); + + query.where("test", isLessThan: 1); + verify(mockWebQuery.where("test", "<", 1)); + + query.where("test", isLessThanOrEqualTo: 1); + verify(mockWebQuery.where("test", "<=", 1)); + + query.where("test", isEqualTo: 1); + verify(mockWebQuery.where("test", "==", 1)); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart new file mode 100644 index 000000000000..28ebd3587da7 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -0,0 +1,56 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. 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:js' as js; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:firebase_core_web/firebase_core_web.dart'; +import 'package:mockito/mockito.dart'; +import 'package:firebase/firestore.dart' as web; + +import 'package:cloud_firestore_web/src/document_reference_web.dart'; +import 'package:cloud_firestore_web/src/query_web.dart'; + +const kCollectionId = "test"; + +class MockWebDocumentSnapshot extends Mock implements web.DocumentSnapshot {} + +class MockWebSnapshotMetaData extends Mock implements web.SnapshotMetadata {} + +class MockFirestoreWeb extends Mock implements web.Firestore {} + +class MockWebTransaction extends Mock implements web.Transaction {} + +class MockWebWriteBatch extends Mock implements web.WriteBatch {} + +class MockDocumentReference extends Mock implements DocumentReferenceWeb {} + +class MockFirestore extends Mock implements FirestoreWeb {} + +class MockWebDocumentReference extends Mock implements web.DocumentReference {} + +class MockWebCollectionReference extends Mock + implements web.CollectionReference {} + +class MockQueryWeb extends Mock implements QueryWeb {} + +class MockDocumentSnapshot extends Mock implements DocumentSnapshotPlatform {} + +web.Firestore mockFirestore() { + final mockFirestoreWeb = MockFirestoreWeb(); + final js.JsObject firebaseMock = js.JsObject.jsify({ + 'firestore': js.allowInterop((_) => mockFirestoreWeb), + 'app': js.allowInterop((String name) { + return js.JsObject.jsify({ + 'name': name, + 'options': {'appId': '123'}, + }); + }) + }); + js.context['firebase'] = firebaseMock; + FirebaseCorePlatform.instance = FirebaseCoreWeb(); + FirestorePlatform.instance = FirestoreWeb(); + return mockFirestoreWeb; +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart new file mode 100644 index 000000000000..e7f243862cbe --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/transaction_web_test.dart @@ -0,0 +1,56 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn("chrome") +import 'package:cloud_firestore_web/src/transaction_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'test_common.dart'; + +void main() { + group("$TransactionWeb()", () { + final mockWebTransaction = MockWebTransaction(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockDocumentReference = MockDocumentReference(); + final mockFirestore = MockFirestore(); + final transaction = TransactionWeb(mockWebTransaction, mockFirestore); + + setUp(() { + when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); + }); + + test("delete", () async { + await transaction.delete(mockDocumentReference); + verify(mockWebTransaction.delete(mockWebDocumentReference)); + }); + + test("get", () async { + final mockWebSnapshot = MockWebDocumentSnapshot(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockWebSnapshotMetaData = MockWebSnapshotMetaData(); + when(mockWebSnapshotMetaData.hasPendingWrites).thenReturn(true); + when(mockWebSnapshotMetaData.fromCache).thenReturn(true); + when(mockWebDocumentReference.path).thenReturn("test/path"); + when(mockWebSnapshot.ref).thenReturn(mockWebDocumentReference); + when(mockWebSnapshot.data()).thenReturn(Map()); + when(mockWebSnapshot.metadata).thenReturn(mockWebSnapshotMetaData); + + when(mockWebTransaction.get(any)) + .thenAnswer((_) => Future.value(mockWebSnapshot)); + await transaction.get(mockDocumentReference); + verify(mockWebTransaction.get(any)); + }); + + test("set", () async { + await transaction.set(mockDocumentReference, {}); + verify(mockWebTransaction.set(mockWebDocumentReference, {})); + }); + + test("update", () async { + await transaction.update(mockDocumentReference, {}); + verify(mockWebTransaction.update(mockWebDocumentReference, + data: argThat(equals({}), named: "data"))); + }); + }); +} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart new file mode 100644 index 000000000000..b947386de664 --- /dev/null +++ b/packages/cloud_firestore/cloud_firestore_web/test/write_batch_web_test.dart @@ -0,0 +1,38 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +@TestOn("chrome") +import 'package:cloud_firestore_web/src/write_batch_web.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'test_common.dart'; + +void main() { + group("$WriteBatchWeb()", () { + final mockWebTransaction = MockWebWriteBatch(); + final mockWebDocumentReference = MockWebDocumentReference(); + final mockDocumentReference = MockDocumentReference(); + final transaction = WriteBatchWeb(mockWebTransaction); + + setUp(() { + when(mockDocumentReference.delegate).thenReturn(mockWebDocumentReference); + }); + + test("delete", () async { + await transaction.delete(mockDocumentReference); + verify(mockWebTransaction.delete(mockWebDocumentReference)); + }); + + test("setData", () async { + await transaction.setData(mockDocumentReference, {}); + verify(mockWebTransaction.set(mockWebDocumentReference, {}, null)); + }); + + test("updateData", () async { + await transaction.updateData(mockDocumentReference, {}); + verify(mockWebTransaction.update(mockWebDocumentReference, + data: argThat(equals({}), named: "data"))); + }); + }); +} From cd5783cce390dd65d4e3e0f2787cc7d497ea135b Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 7 Feb 2020 15:50:20 +0000 Subject: [PATCH 139/144] renamed `firestore_web` to `cloud_firestore_web` --- .../{firestore_web.dart => cloud_firestore_web.dart} | 10 +++++----- .../lib/src/utils/codec_utility.dart | 5 +++-- .../cloud_firestore_web/test/query_web_test.dart | 4 ++-- .../cloud_firestore_web/test/test_common.dart | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) rename packages/cloud_firestore/cloud_firestore_web/lib/{firestore_web.dart => cloud_firestore_web.dart} (91%) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart similarity index 91% rename from packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart rename to packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart index 0558b9b28597..bd8dc117c53e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart @@ -17,18 +17,18 @@ import 'package:cloud_firestore_web/src/write_batch_web.dart'; /// Web implementation for [FirestorePlatform] /// delegates calls to firestore web plugin -class FirestoreWeb extends FirestorePlatform { +class CloudFirestoreWeb extends FirestorePlatform { /// instance of Firestore from the web plugin final Firestore _webFirestore; /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { - FirestorePlatform.instance = FirestoreWeb(); + FirestorePlatform.instance = CloudFirestoreWeb(); } - /// Builds an instance of [FirestoreWeb] with an optional [FirebaseApp] instance + /// Builds an instance of [CloudFirestoreWeb] with an optional [FirebaseApp] instance /// If [app] is null then the created instance will use the default [FirebaseApp] - FirestoreWeb({FirebaseApp app}) + CloudFirestoreWeb({FirebaseApp app}) : _webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), super(app: app ?? FirebaseApp.instance) { @@ -36,7 +36,7 @@ class FirestoreWeb extends FirestorePlatform { } @override - FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); + FirestorePlatform withApp(FirebaseApp app) => CloudFirestoreWeb(app: app); @override CollectionReferencePlatform collection(String path) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index 1d6145c5c6c1..f9a1d316dec0 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -5,7 +5,7 @@ import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase/firestore.dart' as web; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/cloud_firestore_web.dart'; import 'package:cloud_firestore_web/src/document_reference_web.dart'; import 'package:cloud_firestore_web/src/field_value_web.dart'; @@ -77,7 +77,8 @@ class CodecUtility { } else if (value is web.Blob) { return Blob(value.toUint8Array()); } else if (value is web.DocumentReference) { - return (FirestorePlatform.instance as FirestoreWeb).document(value.path); + return (FirestorePlatform.instance as CloudFirestoreWeb) + .document(value.path); } else if (value is Map) { return decodeMapData(value); } else if (value is List) { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index 0f853317e7c4..6dc0deae2c8e 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -4,7 +4,7 @@ @TestOn("chrome") import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/cloud_firestore_web.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:firebase/firestore.dart' as web; @@ -13,7 +13,7 @@ import 'test_common.dart'; class MockWebQuery extends Mock implements web.Query {} -class MockFirestoreWeb extends Mock implements FirestoreWeb {} +class MockFirestoreWeb extends Mock implements CloudFirestoreWeb {} class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 28ebd3587da7..0f032b09ae56 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -4,7 +4,7 @@ import 'dart:js' as js; import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; -import 'package:cloud_firestore_web/firestore_web.dart'; +import 'package:cloud_firestore_web/cloud_firestore_web.dart'; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; import 'package:firebase_core_web/firebase_core_web.dart'; import 'package:mockito/mockito.dart'; @@ -27,7 +27,7 @@ class MockWebWriteBatch extends Mock implements web.WriteBatch {} class MockDocumentReference extends Mock implements DocumentReferenceWeb {} -class MockFirestore extends Mock implements FirestoreWeb {} +class MockFirestore extends Mock implements CloudFirestoreWeb {} class MockWebDocumentReference extends Mock implements web.DocumentReference {} @@ -51,6 +51,6 @@ web.Firestore mockFirestore() { }); js.context['firebase'] = firebaseMock; FirebaseCorePlatform.instance = FirebaseCoreWeb(); - FirestorePlatform.instance = FirestoreWeb(); + FirestorePlatform.instance = CloudFirestoreWeb(); return mockFirestoreWeb; } From 45a876ed82a17317ba0630b6dfad799a0dcec488 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 7 Feb 2020 19:52:55 +0000 Subject: [PATCH 140/144] Update packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart Co-Authored-By: Collin Jackson --- .../cloud_firestore_web/lib/src/field_value_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart index c3e7e5c38881..167802590087 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/field_value_web.dart @@ -11,6 +11,6 @@ class FieldValueWeb extends FieldValuePlatform { /// The js-interop delegate for this [FieldValuePlatform] web.FieldValue data; - /// Constructor. + /// Constructs a web version of [FieldValuePlatform] wrapping a web [FieldValue]. FieldValueWeb(this.data) : super(); } From ebd6e24a221633f3b8d02ede990be8fff33dda6d Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 7 Feb 2020 19:53:06 +0000 Subject: [PATCH 141/144] Update packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart Co-Authored-By: Collin Jackson --- .../cloud_firestore/cloud_firestore_web/lib/src/query_web.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index bd677246ab0a..cd7aca4ce0d3 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -18,7 +18,7 @@ class QueryWeb extends QueryPlatform { static const _kChangeTypeModified = "modified"; static const _kChangeTypeRemoved = "removed"; - /// Builds an instance of [QueryWeb] using [_path] & [_webQuery] + /// Builds an instance of [QueryWeb] delegating to a package:firebase [Query] /// to delegate queries to underlying firestore web plugin QueryWeb( this._firestore, From 79274304acce690fd6003163cb64a78e1cf40a3d Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Fri, 7 Feb 2020 20:01:10 +0000 Subject: [PATCH 142/144] hide webFirestore --- .../lib/src/collection_reference_web.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index a75131e7e2b9..39c7055807c9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -12,7 +12,7 @@ import 'package:cloud_firestore_web/src/query_web.dart'; /// Web implementation for Firestore [CollectionReferencePlatform] class CollectionReferenceWeb extends CollectionReferencePlatform { /// instance of Firestore from the web plugin - final web.Firestore webFirestore; + final web.Firestore _webFirestore; final FirestorePlatform _firestorePlatform; final List pathComponents; // disabling lint as it's only visible for testing @@ -22,11 +22,11 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { /// Creates an instance of [CollectionReferenceWeb] which represents path /// at [pathComponents] and uses implementation of [webFirestore] CollectionReferenceWeb( - this._firestorePlatform, this.webFirestore, this.pathComponents) + this._firestorePlatform, this._webFirestore, this.pathComponents) : queryDelegate = QueryWeb( _firestorePlatform, pathComponents.join("/"), - webFirestore.collection(pathComponents.join("/")), + _webFirestore.collection(pathComponents.join("/")), ), super(_firestorePlatform, pathComponents); @@ -36,7 +36,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { return null; } return DocumentReferenceWeb( - webFirestore, + _webFirestore, firestore, (List.from(pathComponents)..removeLast()), ); @@ -47,13 +47,13 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { List childPath; if (path == null) { web.DocumentReference doc = - webFirestore.collection(pathComponents.join('/')).doc(); + _webFirestore.collection(pathComponents.join('/')).doc(); childPath = doc.path.split('/'); } else { childPath = List.from(pathComponents)..addAll(path.split(('/'))); } return DocumentReferenceWeb( - webFirestore, + _webFirestore, firestore, childPath, ); From c424237175c3b4f6f77a8ed24a70da1ebdb069f4 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sat, 8 Feb 2020 08:14:30 +0000 Subject: [PATCH 143/144] Encode values using in Query#where --- .../lib/src/query_web.dart | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index cd7aca4ce0d3..e5e7f262e715 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_web/src/utils/codec_utility.dart'; import 'package:firebase/firestore.dart' as web; import 'package:cloud_firestore_web/src/utils/document_reference_utils.dart'; @@ -201,39 +202,39 @@ class QueryWeb extends QueryPlatform { assert(field is String || field is FieldPath, 'Supported [field] types are [String] and [FieldPath].'); assert(_webQuery != null); - dynamic usableField = field; + dynamic usableField = CodecUtility.valueEncode(field); if (field == FieldPath.documentId) { usableField = web.FieldPath.documentId(); } web.Query query = _webQuery; if (isEqualTo != null) { - query = query.where(usableField, "==", isEqualTo); + query = query.where(usableField, "==", CodecUtility.valueEncode(isEqualTo)); } if (isLessThan != null) { - query = query.where(usableField, "<", isLessThan); + query = query.where(usableField, "<", CodecUtility.valueEncode(isLessThan)); } if (isLessThanOrEqualTo != null) { - query = query.where(usableField, "<=", isLessThanOrEqualTo); + query = query.where(usableField, "<=", CodecUtility.valueEncode(isLessThanOrEqualTo)); } if (isGreaterThan != null) { - query = query.where(usableField, ">", isGreaterThan); + query = query.where(usableField, ">", CodecUtility.valueEncode(isGreaterThan)); } if (isGreaterThanOrEqualTo != null) { - query = query.where(usableField, ">=", isGreaterThanOrEqualTo); + query = query.where(usableField, ">=", CodecUtility.valueEncode(isGreaterThanOrEqualTo)); } if (arrayContains != null) { - query = query.where(usableField, "array-contains", arrayContains); + query = query.where(usableField, "array-contains", CodecUtility.valueEncode(arrayContains)); } if (arrayContainsAny != null) { assert(arrayContainsAny.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(usableField, "array-contains-any", arrayContainsAny); + query = query.where(usableField, "array-contains-any", CodecUtility.valueEncode(arrayContainsAny)); } if (whereIn != null) { assert( whereIn.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(usableField, "in", whereIn); + query = query.where(usableField, "in", CodecUtility.valueEncode(whereIn)); } if (isNull != null) { assert( From 04a00ca0069d50d18b501e6246b4e221063f4186 Mon Sep 17 00:00:00 2001 From: Amr Yousef Date: Sun, 9 Feb 2020 22:18:12 +0000 Subject: [PATCH 144/144] - Removed pathComponents - Revered FirestoreWeb rename --- .../lib/cloud_firestore_web.dart | 8 +++---- .../lib/src/collection_reference_web.dart | 3 +-- .../lib/src/query_web.dart | 21 ++++++++++++------- .../lib/src/utils/codec_utility.dart | 3 +-- .../test/query_web_test.dart | 2 +- .../cloud_firestore_web/test/test_common.dart | 4 ++-- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart index bd8dc117c53e..291880726be8 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/cloud_firestore_web.dart @@ -17,18 +17,18 @@ import 'package:cloud_firestore_web/src/write_batch_web.dart'; /// Web implementation for [FirestorePlatform] /// delegates calls to firestore web plugin -class CloudFirestoreWeb extends FirestorePlatform { +class FirestoreWeb extends FirestorePlatform { /// instance of Firestore from the web plugin final Firestore _webFirestore; /// Called by PluginRegistry to register this plugin for Flutter Web static void registerWith(Registrar registrar) { - FirestorePlatform.instance = CloudFirestoreWeb(); + FirestorePlatform.instance = FirestoreWeb(); } /// Builds an instance of [CloudFirestoreWeb] with an optional [FirebaseApp] instance /// If [app] is null then the created instance will use the default [FirebaseApp] - CloudFirestoreWeb({FirebaseApp app}) + FirestoreWeb({FirebaseApp app}) : _webFirestore = firebase .firestore(firebase.app((app ?? FirebaseApp.instance).name)), super(app: app ?? FirebaseApp.instance) { @@ -36,7 +36,7 @@ class CloudFirestoreWeb extends FirestorePlatform { } @override - FirestorePlatform withApp(FirebaseApp app) => CloudFirestoreWeb(app: app); + FirestorePlatform withApp(FirebaseApp app) => FirestoreWeb(app: app); @override CollectionReferencePlatform collection(String path) { diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart index 39c7055807c9..7cc586951865 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/collection_reference_web.dart @@ -14,7 +14,6 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { /// instance of Firestore from the web plugin final web.Firestore _webFirestore; final FirestorePlatform _firestorePlatform; - final List pathComponents; // disabling lint as it's only visible for testing @visibleForTesting QueryWeb queryDelegate; // ignore: public_member_api_docs @@ -22,7 +21,7 @@ class CollectionReferenceWeb extends CollectionReferencePlatform { /// Creates an instance of [CollectionReferenceWeb] which represents path /// at [pathComponents] and uses implementation of [webFirestore] CollectionReferenceWeb( - this._firestorePlatform, this._webFirestore, this.pathComponents) + this._firestorePlatform, this._webFirestore, List pathComponents) : queryDelegate = QueryWeb( _firestorePlatform, pathComponents.join("/"), diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart index e5e7f262e715..aa30435580b9 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/query_web.dart @@ -209,27 +209,34 @@ class QueryWeb extends QueryPlatform { web.Query query = _webQuery; if (isEqualTo != null) { - query = query.where(usableField, "==", CodecUtility.valueEncode(isEqualTo)); + query = + query.where(usableField, "==", CodecUtility.valueEncode(isEqualTo)); } if (isLessThan != null) { - query = query.where(usableField, "<", CodecUtility.valueEncode(isLessThan)); + query = + query.where(usableField, "<", CodecUtility.valueEncode(isLessThan)); } if (isLessThanOrEqualTo != null) { - query = query.where(usableField, "<=", CodecUtility.valueEncode(isLessThanOrEqualTo)); + query = query.where( + usableField, "<=", CodecUtility.valueEncode(isLessThanOrEqualTo)); } if (isGreaterThan != null) { - query = query.where(usableField, ">", CodecUtility.valueEncode(isGreaterThan)); + query = query.where( + usableField, ">", CodecUtility.valueEncode(isGreaterThan)); } if (isGreaterThanOrEqualTo != null) { - query = query.where(usableField, ">=", CodecUtility.valueEncode(isGreaterThanOrEqualTo)); + query = query.where( + usableField, ">=", CodecUtility.valueEncode(isGreaterThanOrEqualTo)); } if (arrayContains != null) { - query = query.where(usableField, "array-contains", CodecUtility.valueEncode(arrayContains)); + query = query.where(usableField, "array-contains", + CodecUtility.valueEncode(arrayContains)); } if (arrayContainsAny != null) { assert(arrayContainsAny.length <= 10, "array contains can have maximum of 10 items"); - query = query.where(usableField, "array-contains-any", CodecUtility.valueEncode(arrayContainsAny)); + query = query.where(usableField, "array-contains-any", + CodecUtility.valueEncode(arrayContainsAny)); } if (whereIn != null) { assert( diff --git a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart index f9a1d316dec0..1d7cd0c4c0af 100644 --- a/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart +++ b/packages/cloud_firestore/cloud_firestore_web/lib/src/utils/codec_utility.dart @@ -77,8 +77,7 @@ class CodecUtility { } else if (value is web.Blob) { return Blob(value.toUint8Array()); } else if (value is web.DocumentReference) { - return (FirestorePlatform.instance as CloudFirestoreWeb) - .document(value.path); + return (FirestorePlatform.instance as FirestoreWeb).document(value.path); } else if (value is Map) { return decodeMapData(value); } else if (value is List) { diff --git a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart index 6dc0deae2c8e..8f57c3264eae 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/query_web_test.dart @@ -13,7 +13,7 @@ import 'test_common.dart'; class MockWebQuery extends Mock implements web.Query {} -class MockFirestoreWeb extends Mock implements CloudFirestoreWeb {} +class MockFirestoreWeb extends Mock implements FirestoreWeb {} class MockWebQuerySnapshot extends Mock implements web.QuerySnapshot {} diff --git a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart index 0f032b09ae56..d95186e6551f 100644 --- a/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart +++ b/packages/cloud_firestore/cloud_firestore_web/test/test_common.dart @@ -27,7 +27,7 @@ class MockWebWriteBatch extends Mock implements web.WriteBatch {} class MockDocumentReference extends Mock implements DocumentReferenceWeb {} -class MockFirestore extends Mock implements CloudFirestoreWeb {} +class MockFirestore extends Mock implements FirestoreWeb {} class MockWebDocumentReference extends Mock implements web.DocumentReference {} @@ -51,6 +51,6 @@ web.Firestore mockFirestore() { }); js.context['firebase'] = firebaseMock; FirebaseCorePlatform.instance = FirebaseCoreWeb(); - FirestorePlatform.instance = CloudFirestoreWeb(); + FirestorePlatform.instance = FirestoreWeb(); return mockFirestoreWeb; }