Skip to content

[cloud_firestore] Strip Document Reference firestore equality to solve equality & map key bug #2081 - #2110

Closed
duttaoindril wants to merge 7 commits into
firebase:masterfrom
duttaoindril:patch-1
Closed

duttaoindril wants to merge 7 commits into
firebase:masterfrom
duttaoindril:patch-1

Conversation

@duttaoindril

@duttaoindril duttaoindril commented Mar 3, 2020 •

Copy link
Copy Markdown

Description

Due to #2081, I've decided to create a simple proposal - a patch fix for the error. It simply removes the firestore equality check to let DocumentReference checking be done solely on the path.

The expected behavior is for DocumentReference to be a valid key in a map. However, due to #2081, simply using DocumentReference as a key in a map is not possible.

First, let me confirm that equality between keys is needed for a map in Dart.

Creating a dummy class as such below:

class KeyTester {
  final String data;

  KeyTester(this.data);

  // Always returns the same hashcode
  @override
  int get hashCode => 10000;

  // Always returns not equal to any other object
  @override
  bool operator ==(dynamic o) => false;
}

And running the code below:

// Instantiate an instance `KeyTester` keyA
KeyTester key = KeyTester("KeyA");

// Create a map with key type KeyTester
Map<KeyTester, String> map = {
  key: 'Key',
};

// Even though I use the same instance of `KeyTester`, `.ey`, `map` still returns null. And it doesn't know if it contains that key. Even though, by the third check, it's obvious that they are the same key/

print("Map Data @ Key: ${map[key]}");
// Map Data @ Key: null

print("Map Key Exists: ${map.containsKey(key)}");
// Map Key Exists: false
  
print("Key Equality: ${key.data == map.keys.toList()[0].data}");
// Key Equality: true

As you can see from the output above, even with the same hashCode, Dart checks to see if the keys are equal or not.

Extending this to a test using Firestore DocumentReferences, the actual behavior is as follows:

DocumentReference refA = Firestore.instance.document("foo/bar");
DocumentReference refB = Firestore.instance.document("foo/bar");

Map<DocumentReference, String> anotherMap = {
  refA: 'RefA',
};

print("refA: ${refA.path}");
// refA: foo/bar

print("refB: ${refB.path}");
// refB: foo/bar

print("Another Map Key Equality: ${refA.path == refB.path}");
// Another Map Key Equality: true

print("Another Map Data @ Key: ${anotherMap[refA]}");
// Another Map Data @ Key: RefA

print("Another Map Data @ Key: ${anotherMap[refB]}");
// Another Map Data @ Key: null

print("${refA == refB}");
// false

print("${refA.hashCode == refB.hashCode}");
// true

Running the same code above with the changes proposed yields the following results, the expected results:

print("Another Map Data @ Key: ${anotherMap[refA]}");
// Another Map Data @ Key: RefA

print("Another Map Data @ Key: ${anotherMap[refB]}");
// Another Map Data @ Key: RefA

print("${refA == refB}");
// false

print("${refA.hashCode == refB.hashCode}");
// false

Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • If the pull request affects only one plugin, the PR title starts with the name of the plugin in brackets (e.g. [cloud_firestore])
  • My PR includes unit or integration tests for all changed/updated/fixed behaviors (See [Contributor Guide]).
  • All existing and new tests are passing.
  • I updated/added relevant documentation (doc comments with ///).
  • The analyzer (flutter analyze) does not report any problems on my PR.
  • I read and followed the [Flutter Style Guide].
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy].
  • I updated CHANGELOG.md to add a description of the change.
  • I signed the [CLA].
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require plugin users to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (please indicate a breaking change in CHANGELOG.md and increment major revision).
  • No, this is not a breaking change.

@googlebot

Copy link
Copy Markdown

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

馃摑 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

鈩癸笍 Googlers: Go here for more info.

@duttaoindril

Copy link
Copy Markdown
Author

@googlebot I signed it!

@googlebot

Copy link
Copy Markdown

CLAs look good, thanks!

鈩癸笍 Googlers: Go here for more info.

@googlebot googlebot added cla: yes and removed cla: no labels Mar 3, 2020
@duttaoindril duttaoindril changed the title [cloud_firestore] (WIP) Strip Document Reference firestore equality to solve equality & map key bug #2081 [cloud_firestore] Strip Document Reference firestore equality to solve equality & map key bug #2081 Mar 3, 2020
@duttaoindril

duttaoindril commented Mar 3, 2020 •

Copy link
Copy Markdown
Author

https://github.com/FirebaseExtended/flutterfire/pull/2110/checks?check_run_id=481504083

No idea why this check is failing; seems to not be related to this PR.

@Salakar

Salakar commented Jul 7, 2020

Copy link
Copy Markdown
Contributor

Hey @duttaoindril - thanks for taking to time to send up this PR. As part of our on-going work for #2582, this has been resolved in our Firebase Firestore rework (#2913) - which has now been merged into master. We'll look at publishing some prereleases in the next few days.

@Salakar Salakar closed this Jul 7, 2020
@firebase firebase locked and limited conversation to collaborators Aug 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants