Skip to content

Migrate CPP SDK from FieldValue to Protobuf #577

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
Aug 18, 2021

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Jul 26, 2021

This changes the internals of the Firestore C++ to use the updated code on iOS, which drops model::FieldValue in favor of using Protobuf directly.

I did not port the UserDataReader/UserDataWriter refactor, but we can do that as a follow up.

This will not build until the next iOS Release.

@google-cla google-cla bot added the cla: yes label Jul 26, 2021
}

size_t FieldValueInternal::blob_size() const {
SIMPLE_HARD_ASSERT(type_ == Type::kBlob);
return absl::get<model::FieldValue>(value_).blob_value().size();
auto value =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

const uint8_t* FieldValueInternal::blob_value() const {
SIMPLE_HARD_ASSERT(type_ == Type::kBlob);
return absl::get<model::FieldValue>(value_).blob_value().data();
auto value =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/auto/auto*/.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

FieldValueInternal::FieldValueInternal(bool value)
: type_{Type::kBoolean}, value_{model::FieldValue::FromBoolean(value)} {}
FieldValueInternal::FieldValueInternal(bool value) : type_{Type::kBoolean} {
auto proto = absl::get<SharedMessage<google_firestore_v1_Value>>(value_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. An alias for SharedMessage<google_firestore_v1_Value> would help reduce some of this verbosity -- something like
using ProtoValueT = SharedMessage<google_firestore_v1_Value>;
  1. absl::get<SharedMessage<google_firestore_v1_Value>> is repeated so many times, it might make sense to create a helper function for it along the lines of:
ProtoValueT& GetValue() {
  return absl::get<SharedMessage<google_firestore_v1_Value>>(value_);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absl::get returns a reference, so this could be auto& proto to avoid an unnecessary copy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the helper method, which reduces the number of SharedMessage<google_firestore_v1_Value> types significantly. I do not think we need an alias anymore.

Also changes all access to references.

const std::string& key = kv.first;
const FieldValue& value = kv.second;

auto parsedValue = ParseData(value, context.ChildContext(key));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: s/parsedValue/parsed_value/.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}
}

return model::ObjectValue::FromMap(std::move(result));
return std::move(result);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary (and sometimes can be slightly harmful to performance) to move when returning local variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

for (pb_size_t i = 0; i < object.fields_count; ++i) {
std::string key = MakeString(object.fields[i].key);
const google_firestore_v1_Value& value = object.fields[i].value;
result[key] = ConvertAnyValue(value, stb);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: you can move key.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


api::DocumentReference api_reference{reference.key(), snapshot_.firestore()};
api::DocumentReference api_reference{key, snapshot_.firestore()};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably move key.

@@ -190,10 +210,10 @@ core::Bound QueryInternal::ToBound(
SimpleThrowInvalidArgument(message);
}

components.push_back(std::move(value).value());
components->values[i] = *DeepClone(*value).release();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: why is DeepClone necessary here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory is owned by the DocumentSnapshot and we need to move ownership to the query bound. See here: https://github.com/firebase/firebase-ios-sdk/blob/e8f419baf275899068e915a6c2ecb4ae1e43d264/Firestore/Source/API/FIRQuery.mm#L584

SimpleThrowInvalidArgument(
"Invalid query. Expected a string for the document ID.");
}
const std::string& document_id = from.string_value();
const std::string& document_id = MakeString(from->string_value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make document_id a non-reference variable to avoid attaching a reference to a temporary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor Author

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick review. I addressed your feedback, but I did not verify the build. I will wait until this is ready for merging until I assign this back.

for (pb_size_t i = 0; i < object.fields_count; ++i) {
std::string key = MakeString(object.fields[i].key);
const google_firestore_v1_Value& value = object.fields[i].value;
result[key] = ConvertAnyValue(value, stb);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

FieldValueInternal::FieldValueInternal(bool value)
: type_{Type::kBoolean}, value_{model::FieldValue::FromBoolean(value)} {}
FieldValueInternal::FieldValueInternal(bool value) : type_{Type::kBoolean} {
auto proto = absl::get<SharedMessage<google_firestore_v1_Value>>(value_);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the helper method, which reduces the number of SharedMessage<google_firestore_v1_Value> types significantly. I do not think we need an alias anymore.

Also changes all access to references.

}

const uint8_t* FieldValueInternal::blob_value() const {
SIMPLE_HARD_ASSERT(type_ == Type::kBlob);
return absl::get<model::FieldValue>(value_).blob_value().data();
auto value =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

size_t FieldValueInternal::blob_size() const {
SIMPLE_HARD_ASSERT(type_ == Type::kBlob);
return absl::get<model::FieldValue>(value_).blob_value().size();
auto value =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -190,10 +210,10 @@ core::Bound QueryInternal::ToBound(
SimpleThrowInvalidArgument(message);
}

components.push_back(std::move(value).value());
components->values[i] = *DeepClone(*value).release();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory is owned by the DocumentSnapshot and we need to move ownership to the query bound. See here: https://github.com/firebase/firebase-ios-sdk/blob/e8f419baf275899068e915a6c2ecb4ae1e43d264/Firestore/Source/API/FIRQuery.mm#L584

SimpleThrowInvalidArgument(
"Invalid query. Expected a string for the document ID.");
}
const std::string& document_id = from.string_value();
const std::string& document_id = MakeString(from->string_value);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const std::string& key = kv.first;
const FieldValue& value = kv.second;

auto parsedValue = ParseData(value, context.ChildContext(key));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

}
}

return model::ObjectValue::FromMap(std::move(result));
return std::move(result);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@schmidt-sebastian schmidt-sebastian force-pushed the mrschmidt/fieldvalue branch 3 times, most recently from bc9e33d to ec39332 Compare July 28, 2021 18:48
@schmidt-sebastian schmidt-sebastian added the tests-requested: quick Trigger a quick set of integration tests. label Jul 29, 2021
var-const
var-const previously approved these changes Aug 6, 2021
@github-actions github-actions bot dismissed var-const’s stale review August 10, 2021 00:52

🍞 Dismissed stale approval on external PR.

@schmidt-sebastian schmidt-sebastian added tests-requested: quick Trigger a quick set of integration tests. and removed tests-requested: quick Trigger a quick set of integration tests. labels Aug 10, 2021
@github-actions github-actions bot removed the tests-requested: quick Trigger a quick set of integration tests. label Aug 10, 2021
@github-actions github-actions bot added the tests: failed This PR's integration tests failed. label Aug 18, 2021
@firebase-workflow-trigger firebase-workflow-trigger bot removed the tests: in-progress This PR's integration tests are in progress. label Aug 18, 2021
@schmidt-sebastian schmidt-sebastian added tests-requested: quick Trigger a quick set of integration tests. and removed tests: failed This PR's integration tests failed. labels Aug 18, 2021
@github-actions github-actions bot added tests: in-progress This PR's integration tests are in progress. and removed tests-requested: quick Trigger a quick set of integration tests. labels Aug 18, 2021
@github-actions github-actions bot added the tests: failed This PR's integration tests failed. label Aug 18, 2021
@@ -37,7 +37,7 @@ def firebaseDependenciesMap = [
'com.google.flatbuffers:flatbuffers-java:1.12.0',
'com.google.android.gms:play-services-base:17.6.0'],
'performance' : ['com.google.firebase:firebase-perf:20.0.2'],
'remote_config' : ['com.google.firebase:firebase-config:21.0.0',
'remote_config' : ['com.google.firebase:firebase-config:21.0.1',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is part of the version update that we want to release.

@@ -14,7 +14,7 @@ on:
required: true
apis:
description: 'CSV of apis to build and test'
default: 'admob,analytics,auth,database,dynamic_links,firestore,functions,installations,messaging,remote_config,storage'
default: 'firestore'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change needs to be reverted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

@@ -80,7 +80,7 @@ def validate_results_unity(log_text):
# After the result string comes a list of failing testapps.
summary = log_text[results_match.start():]
else:
summary = _tail(log_text, 15)
summary = _tail(log_text, 1500000)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be reverted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

@schmidt-sebastian schmidt-sebastian added tests-requested: full Trigger a FULL set of integration tests (uses expanded test matrix). and removed tests: in-progress This PR's integration tests are in progress. tests: failed This PR's integration tests failed. labels Aug 18, 2021
@github-actions github-actions bot added tests: in-progress This PR's integration tests are in progress. tests: failed This PR's integration tests failed. and removed tests-requested: full Trigger a FULL set of integration tests (uses expanded test matrix). labels Aug 18, 2021
@firebase-workflow-trigger firebase-workflow-trigger bot removed the tests: in-progress This PR's integration tests are in progress. label Aug 18, 2021
@a-maurice a-maurice removed the tests: failed This PR's integration tests failed. label Aug 18, 2021
@schmidt-sebastian schmidt-sebastian merged commit 4725fa6 into main Aug 18, 2021
@github-actions github-actions bot added the tests: in-progress This PR's integration tests are in progress. label Aug 18, 2021
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/fieldvalue branch August 18, 2021 20:59
@firebase firebase locked and limited conversation to collaborators Sep 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api: firestore cla: yes tests: in-progress This PR's integration tests are in progress.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants