diff --git a/packages/firebase_data_connect/firebase_data_connect/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_data_connect/firebase_data_connect/example/android/app/src/main/AndroidManifest.xml
index 843b956968dd..6a3a3ac5ac03 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/android/app/src/main/AndroidManifest.xml
+++ b/packages/firebase_data_connect/firebase_data_connect/example/android/app/src/main/AndroidManifest.xml
@@ -43,4 +43,4 @@
-
\ No newline at end of file
+
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/.dataconnect/schema/prelude.gql b/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/.dataconnect/schema/prelude.gql
index c75ac521add7..54eee276ad8a 100755
--- a/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/.dataconnect/schema/prelude.gql
+++ b/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/.dataconnect/schema/prelude.gql
@@ -46,6 +46,17 @@ directive @auth(
"""
expr: Boolean_Expr @fdc_oneOf(required: true)
) on QUERY | MUTATION
+
+"""
+Marks an element of a GraphQL operation as no longer supported on the client.
+The Firebase Data Connect backend will still support this element, but it will
+no longer appear in generated SDKs.
+"""
+directive @retired(
+ "Explains why this element was retired."
+ reason: String
+) on QUERY | MUTATION | FIELD | VARIABLE_DEFINITION
+
"Query filter criteria for `String` scalar fields."
input String_Filter {
"When true, match if field `IS NULL`. When false, match if field is `NOT NULL`."
@@ -304,6 +315,7 @@ input Any_ListFilter {
"Match if list field does not contain any of the provided values as members."
excludesAll: [Any!]
}
+
"""
(Internal) A string that uniquely identifies a type, field, and so on.
@@ -358,53 +370,7 @@ directive @fdc_generated(
| ENUM_VALUE
| INPUT_OBJECT
| INPUT_FIELD_DEFINITION
-"""
-Defines a database index to optimize query performance.
-
-Given `type TableName @table @index(fields: [“fieldName”, “secondFieldName”])`,
-`table_name_field_name_second_field_name_aa_idx` is the SQL index id.
-`table_name_field_name_second_field_name_ad_idx` if `order: [ASC DESC]`.
-`table_name_field_name_second_field_name_dd_idx` if `order: [DESC DESC]`.
-
-Given `type TableName @table { fieldName: Int @index } `
-`table_name_field_name_idx` is the SQL index id.
-`order` matters less for single field indexes because they can be scanned in both ways.
-
-Override with `@index(name)` in case of index name conflicts.
-"""
-directive @index(
- "The SQL database index id. Defaults to __idx."
- name: String
- """
- Only allowed and required when used on OBJECT.
- The fields to create an index on.
- """
- fields: [String!]
- """
- Only allowed when used on OBJECT and BTREE index.
- Index order of each column. Default to all ASC.
- """
- order: [IndexFieldOrder!]
- """
- For array field, default to `GIN`.
- For Vector field, default to `HNSW`.
- """
- type: IndexType
- """
- Only allowed when used on vector field.
- The vector similarity method. Default to `INNER_PRODUCT`.
- """
- vector_method: VectorSimilarityMethod
-) repeatable on FIELD_DEFINITION | OBJECT
-enum IndexFieldOrder { ASC DESC }
-
-enum IndexType {
- BTREE
- GIN
- HNSW
- IVFFLAT
-}
type Query {
_service: _Service!
}
@@ -415,7 +381,10 @@ type Mutation {
}
type _Service {
+ "Full Service Definition Language of the Frebase Data Connect Schema, including normalized schema, predefined and generated types."
sdl: String!
+ "Orignal Schema Sources in the service."
+ schema: String!
}
"(Internal) Added to things that may be removed from FDC and will soon be no longer usable in schema or operations."
@@ -465,6 +434,7 @@ directive @fdc_oneOf(
"If true, exactly one field / argument in the group must be specified."
required: Boolean! = false
) repeatable on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
+
"""
UUID is a string with hex digits representing an RFC4122 value.
@@ -490,16 +460,7 @@ scalar True
@fdc_forbiddenAsFieldType
@fdc_forbiddenAsVariableType
@fdc_example(value: true, description: "The only allowed value.")
-"Define the intervals used in timestamps and dates (subset)"
-enum TimestampInterval @fdc_deprecated {
- second
- minute
- hour
- day
- week
- month
- year
-}
+
"""
A Common Expression Language (CEL) expression that returns a boolean at runtime.
@@ -566,6 +527,7 @@ scalar Any_SQL
@fdc_sqlExpression
@fdc_forbiddenAsVariableType
@fdc_forbiddenAsFieldType
+
"""
Defines a relational database table.
@@ -718,24 +680,6 @@ enum OrderDirection {
DESC
}
-enum ColDefault @fdc_deprecated {
- """
- Generates a random UUID (v4) as the default column value.
- Compatible with String or UUID typed fields.
- """
- UUID
- """
- Generates an auto-incrementing sequence as the default column value.
- Compatible with Int and Int64 typed fields.
- """
- SEQUENCE
- """
- Populates the default column value with the current date or timestamp.
- Compatible with Date and Timestamp typed fields.
- """
- NOW
-}
-
"""
Specify the default column value.
@@ -744,8 +688,6 @@ The supported arguments vary based on the field type.
directive @default(
"A constant value. Validated against the field GraphQL type at compile-time."
value: Any @fdc_oneOf(required: true)
- "(Deprecated) Built-in common ways to generate initial value."
- generate: ColDefault @fdc_oneOf(required: true) @deprecated
"A CEL expression, whose return value must match the field data type."
expr: Any_Expr @fdc_oneOf(required: true)
"""
@@ -757,6 +699,75 @@ directive @default(
"""
sql: Any_SQL @fdc_oneOf(required: true)
) on FIELD_DEFINITION
+
+"""
+Defines a database index to optimize query performance.
+
+Given `type TableName @table @index(fields: [“fieldName”, “secondFieldName”])`,
+`table_name_field_name_second_field_name_aa_idx` is the SQL index id.
+`table_name_field_name_second_field_name_ad_idx` if `order: [ASC DESC]`.
+`table_name_field_name_second_field_name_dd_idx` if `order: [DESC DESC]`.
+
+Given `type TableName @table { fieldName: Int @index } `
+`table_name_field_name_idx` is the SQL index id.
+`order` matters less for single field indexes because they can be scanned in both ways.
+
+Override with `@index(name)` in case of index name conflicts.
+"""
+directive @index(
+ "The SQL database index id. Defaults to __idx."
+ name: String
+ """
+ Only allowed and required when used on OBJECT.
+ The fields to create an index on.
+ """
+ fields: [String!]
+ """
+ Only allowed when used on OBJECT and BTREE index.
+ Index order of each column. Default to all ASC.
+ """
+ order: [IndexFieldOrder!]
+ """
+ For array field, default to `GIN`.
+ For Vector field, default to `HNSW`.
+ """
+ type: IndexType
+ """
+ Only allowed when used on vector field.
+ The vector similarity method. Default to `INNER_PRODUCT`.
+ """
+ vector_method: VectorSimilarityMethod
+) repeatable on FIELD_DEFINITION | OBJECT
+
+enum IndexFieldOrder { ASC DESC }
+
+enum IndexType {
+ BTREE
+ GIN
+ HNSW
+ IVFFLAT
+}
+
+"""
+Defines a unique constraint.
+
+Given `type TableName @table @unique(fields: [“fieldName”, “secondFieldName”])`,
+`table_name_field_name_second_field_name_uidx` is the SQL unique index id.
+Given `type TableName @table { fieldName: Int @unique } `
+`table_name_field_name_uidx` is the SQL unique index id.
+
+Override with `@unique(indexName)` in case of index name conflicts.
+"""
+directive @unique(
+ "The SQL database unique index name. Defaults to __uidx."
+ indexName: String
+ """
+ Only allowed and required when used on OBJECT.
+ The fields to create a unique constraint on.
+ """
+ fields: [String!]
+) repeatable on FIELD_DEFINITION | OBJECT
+
"""
Date is a string in the YYYY-MM-DD format representing a local-only date.
@@ -980,25 +991,7 @@ enum Date_Interval @fdc_forbiddenAsFieldType {
MONTH
YEAR
}
-"""
-Defines a unique constraint.
-
-Given `type TableName @table @unique(fields: [“fieldName”, “secondFieldName”])`,
-`table_name_field_name_second_field_name_uidx` is the SQL unique index id.
-Given `type TableName @table { fieldName: Int @unique } `
-`table_name_field_name_uidx` is the SQL unique index id.
-Override with `@unique(indexName)` in case of index name conflicts.
-"""
-directive @unique(
- "The SQL database unique index name. Defaults to __uidx."
- indexName: String
- """
- Only allowed and required when used on OBJECT.
- The fields to create a unique constraint on.
- """
- fields: [String!]
-) repeatable on FIELD_DEFINITION | OBJECT
"Update input of a String value"
input String_Update {
set: String @fdc_oneOf(group: "set")
@@ -1090,6 +1083,7 @@ input Any_ListUpdate {
append: [Any!]
prepend: [Any!]
}
+
"""
Vector is an array of single-precision floating-point numbers, serialized
as a JSON array. All elements must be finite (no NaN, Infinity or -Infinity).
@@ -1168,3 +1162,4 @@ scalar Vector_Embed_Model
@fdc_forbiddenAsVariableType
@fdc_forbiddenAsFieldType
@fdc_example(value: "textembedding-gecko@003", description: "A stable version of the textembedding-gecko model")
+
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/connector/mutations.gql b/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/connector/mutations.gql
index a869f6fea236..d7cc7276a6e5 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/connector/mutations.gql
+++ b/packages/firebase_data_connect/firebase_data_connect/example/dataconnect/connector/mutations.gql
@@ -6,6 +6,17 @@ mutation addDirectorToMovie($personId: Person_Key, $movieId: UUID)
@auth(level: PUBLIC) {
directedBy_insert(data: { directedby: $personId, movieId: $movieId })
}
+mutation seedData @auth(level: PUBLIC) {
+ movies1: movie_insert(
+ data: {
+ title: "The Matrix"
+ releaseYear: 1999
+ genre: "Action"
+ rating: 5.0
+ description: "When a beautiful stranger leads computer hacker Neo to a forbidding underworld, he discovers the shocking truth--the life he knows is the elaborate deception of an evil cyber-intelligence."
+ }
+ )
+}
mutation createMovie(
$title: String!
$releaseYear: Int!
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/firebase.json b/packages/firebase_data_connect/firebase_data_connect/example/firebase.json
index 2d00ab15a830..f8e4ba878186 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/firebase.json
+++ b/packages/firebase_data_connect/firebase_data_connect/example/firebase.json
@@ -7,4 +7,4 @@
"port": 9099
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart
index 0929d0a602b9..a64ab25e9d9e 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_director_to_movie.dart
@@ -4,20 +4,19 @@ class AddDirectorToMovie {
String name = "addDirectorToMovie";
AddDirectorToMovie({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- AddDirectorToMovieResponse.fromJson(
- jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ AddDirectorToMovieData.fromJson(jsonDecode(json) as Map);
Serializer varsSerializer =
(AddDirectorToMovieVariables vars) => jsonEncode(vars.toJson());
- MutationRef ref(
- {AddDirectorToMovieVariablesPersonId? personId,
- String? movieId,
- AddDirectorToMovieVariables? addDirectorToMovieVariables}) {
- AddDirectorToMovieVariables vars1 = AddDirectorToMovieVariables(
+ MutationRef ref({
+ AddDirectorToMovieVariablesPersonId? personId,
+ String? movieId,
+ }) {
+ AddDirectorToMovieVariables vars = AddDirectorToMovieVariables(
personId: personId,
movieId: movieId,
);
- AddDirectorToMovieVariables vars = addDirectorToMovieVariables ?? vars1;
+
return dataConnect.mutation(
this.name, dataDeserializer, varsSerializer, vars);
}
@@ -53,10 +52,10 @@ class AddDirectorToMovieDirectedByInsert {
}
}
-class AddDirectorToMovieResponse {
+class AddDirectorToMovieData {
late AddDirectorToMovieDirectedByInsert directedBy_insert;
- AddDirectorToMovieResponse.fromJson(Map json)
+ AddDirectorToMovieData.fromJson(Map json)
: directedBy_insert = AddDirectorToMovieDirectedByInsert.fromJson(
json['directedBy_insert']) {}
@@ -69,7 +68,7 @@ class AddDirectorToMovieResponse {
return json;
}
- AddDirectorToMovieResponse({
+ AddDirectorToMovieData({
required this.directedBy_insert,
}) {
// TODO(mtewani): Only show this if there are optional fields.
@@ -124,8 +123,8 @@ class AddDirectorToMovieVariables {
}
AddDirectorToMovieVariables({
- AddDirectorToMovieVariablesPersonId? this.personId,
- String? this.movieId,
+ this.personId,
+ this.movieId,
}) {
// TODO(mtewani): Only show this if there are optional fields.
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart
index 9d418952fcd1..22f681927a96 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/add_person.dart
@@ -4,16 +4,17 @@ class AddPerson {
String name = "addPerson";
AddPerson({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- AddPersonResponse.fromJson(jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ AddPersonData.fromJson(jsonDecode(json) as Map);
Serializer varsSerializer =
(AddPersonVariables vars) => jsonEncode(vars.toJson());
- MutationRef ref(
- {String? name, AddPersonVariables? addPersonVariables}) {
- AddPersonVariables vars1 = AddPersonVariables(
+ MutationRef ref({
+ String? name,
+ }) {
+ AddPersonVariables vars = AddPersonVariables(
name: name,
);
- AddPersonVariables vars = addPersonVariables ?? vars1;
+
return dataConnect.mutation(
this.name, dataDeserializer, varsSerializer, vars);
}
@@ -42,10 +43,10 @@ class AddPersonPersonInsert {
}
}
-class AddPersonResponse {
+class AddPersonData {
late AddPersonPersonInsert person_insert;
- AddPersonResponse.fromJson(Map json)
+ AddPersonData.fromJson(Map json)
: person_insert = AddPersonPersonInsert.fromJson(json['person_insert']) {}
// TODO(mtewani): Fix up to create a map on the fly
@@ -57,7 +58,7 @@ class AddPersonResponse {
return json;
}
- AddPersonResponse({
+ AddPersonData({
required this.person_insert,
}) {
// TODO(mtewani): Only show this if there are optional fields.
@@ -82,7 +83,7 @@ class AddPersonVariables {
}
AddPersonVariables({
- String? this.name,
+ this.name,
}) {
// TODO(mtewani): Only show this if there are optional fields.
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart
index 6d1e020cce3b..e070dd38a185 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/create_movie.dart
@@ -4,25 +4,25 @@ class CreateMovie {
String name = "createMovie";
CreateMovie({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- CreateMovieResponse.fromJson(jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ CreateMovieData.fromJson(jsonDecode(json) as Map);
Serializer varsSerializer =
(CreateMovieVariables vars) => jsonEncode(vars.toJson());
- MutationRef ref(
- {required String title,
- required int releaseYear,
- required String genre,
- double? rating,
- String? description,
- CreateMovieVariables? createMovieVariables}) {
- CreateMovieVariables vars1 = CreateMovieVariables(
+ MutationRef ref({
+ required String title,
+ required int releaseYear,
+ required String genre,
+ double? rating,
+ String? description,
+ }) {
+ CreateMovieVariables vars = CreateMovieVariables(
title: title,
releaseYear: releaseYear,
genre: genre,
rating: rating,
description: description,
);
- CreateMovieVariables vars = createMovieVariables ?? vars1;
+
return dataConnect.mutation(
this.name, dataDeserializer, varsSerializer, vars);
}
@@ -52,10 +52,10 @@ class CreateMovieMovieInsert {
}
}
-class CreateMovieResponse {
+class CreateMovieData {
late CreateMovieMovieInsert movie_insert;
- CreateMovieResponse.fromJson(Map json)
+ CreateMovieData.fromJson(Map json)
: movie_insert = CreateMovieMovieInsert.fromJson(json['movie_insert']) {}
// TODO(mtewani): Fix up to create a map on the fly
@@ -67,7 +67,7 @@ class CreateMovieResponse {
return json;
}
- CreateMovieResponse({
+ CreateMovieData({
required this.movie_insert,
}) {
// TODO(mtewani): Only show this if there are optional fields.
@@ -117,8 +117,8 @@ class CreateMovieVariables {
required this.title,
required this.releaseYear,
required this.genre,
- double? this.rating,
- String? this.description,
+ this.rating,
+ this.description,
}) {
// TODO(mtewani): Only show this if there are optional fields.
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart
index 5aeb6cdd1938..970e97c44b3f 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/delete_movie.dart
@@ -4,16 +4,17 @@ class DeleteMovie {
String name = "deleteMovie";
DeleteMovie({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- DeleteMovieResponse.fromJson(jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ DeleteMovieData.fromJson(jsonDecode(json) as Map);
Serializer varsSerializer =
(DeleteMovieVariables vars) => jsonEncode(vars.toJson());
- MutationRef ref(
- {required String id, DeleteMovieVariables? deleteMovieVariables}) {
- DeleteMovieVariables vars1 = DeleteMovieVariables(
+ MutationRef ref({
+ required String id,
+ }) {
+ DeleteMovieVariables vars = DeleteMovieVariables(
id: id,
);
- DeleteMovieVariables vars = deleteMovieVariables ?? vars1;
+
return dataConnect.mutation(
this.name, dataDeserializer, varsSerializer, vars);
}
@@ -43,10 +44,10 @@ class DeleteMovieMovieDelete {
}
}
-class DeleteMovieResponse {
+class DeleteMovieData {
late DeleteMovieMovieDelete? movie_delete;
- DeleteMovieResponse.fromJson(Map json)
+ DeleteMovieData.fromJson(Map json)
: movie_delete = DeleteMovieMovieDelete.fromJson(json['movie_delete']) {}
// TODO(mtewani): Fix up to create a map on the fly
@@ -60,8 +61,8 @@ class DeleteMovieResponse {
return json;
}
- DeleteMovieResponse({
- DeleteMovieMovieDelete? movie_delete,
+ DeleteMovieData({
+ this.movie_delete,
}) {
// TODO(mtewani): Only show this if there are optional fields.
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart
index 58e13493a23e..aacfbc7b0aea 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies.dart
@@ -4,11 +4,12 @@ class ListMovies {
String name = "ListMovies";
ListMovies({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- ListMoviesResponse.fromJson(jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ ListMoviesData.fromJson(jsonDecode(json) as Map);
- QueryRef ref() {
- return dataConnect.query(this.name, dataDeserializer, null, null);
+ QueryRef ref() {
+ return dataConnect.query(
+ this.name, dataDeserializer, emptySerializer, null);
}
FirebaseDataConnect dataConnect;
@@ -72,10 +73,10 @@ class ListMoviesMoviesDirectedBy {
}
}
-class ListMoviesResponse {
+class ListMoviesData {
late List movies;
- ListMoviesResponse.fromJson(Map json)
+ ListMoviesData.fromJson(Map json)
: movies = (json['movies'] as List)
.map((e) => ListMoviesMovies.fromJson(e))
.toList() {}
@@ -89,7 +90,7 @@ class ListMoviesResponse {
return json;
}
- ListMoviesResponse({
+ ListMoviesData({
required this.movies,
}) {
// TODO(mtewani): Only show this if there are optional fields.
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart
index f06a7f68d304..991a71bbc461 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_movies_by_partial_title.dart
@@ -4,21 +4,19 @@ class ListMoviesByPartialTitle {
String name = "ListMoviesByPartialTitle";
ListMoviesByPartialTitle({required this.dataConnect});
- Deserializer dataDeserializer =
- (String json) => ListMoviesByPartialTitleResponse.fromJson(
+ Deserializer dataDeserializer = (String json) =>
+ ListMoviesByPartialTitleData.fromJson(
jsonDecode(json) as Map);
Serializer varsSerializer =
(ListMoviesByPartialTitleVariables vars) => jsonEncode(vars.toJson());
- QueryRef
- ref(
- {required String input,
- ListMoviesByPartialTitleVariables?
- listMoviesByPartialTitleVariables}) {
- ListMoviesByPartialTitleVariables vars1 = ListMoviesByPartialTitleVariables(
+ QueryRef
+ ref({
+ required String input,
+ }) {
+ ListMoviesByPartialTitleVariables vars = ListMoviesByPartialTitleVariables(
input: input,
);
- ListMoviesByPartialTitleVariables vars =
- listMoviesByPartialTitleVariables ?? vars1;
+
return dataConnect.query(this.name, dataDeserializer, varsSerializer, vars);
}
@@ -61,16 +59,16 @@ class ListMoviesByPartialTitleMovies {
required this.id,
required this.title,
required this.genre,
- double? rating,
+ this.rating,
}) {
// TODO(mtewani): Only show this if there are optional fields.
}
}
-class ListMoviesByPartialTitleResponse {
+class ListMoviesByPartialTitleData {
late List movies;
- ListMoviesByPartialTitleResponse.fromJson(Map json)
+ ListMoviesByPartialTitleData.fromJson(Map json)
: movies = (json['movies'] as List)
.map((e) => ListMoviesByPartialTitleMovies.fromJson(e))
.toList() {}
@@ -84,7 +82,7 @@ class ListMoviesByPartialTitleResponse {
return json;
}
- ListMoviesByPartialTitleResponse({
+ ListMoviesByPartialTitleData({
required this.movies,
}) {
// TODO(mtewani): Only show this if there are optional fields.
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart
index 8a4d7e4cb0a6..5fbb80c56558 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/list_persons.dart
@@ -4,11 +4,12 @@ class ListPersons {
String name = "ListPersons";
ListPersons({required this.dataConnect});
- Deserializer dataDeserializer = (String json) =>
- ListPersonsResponse.fromJson(jsonDecode(json) as Map);
+ Deserializer dataDeserializer = (String json) =>
+ ListPersonsData.fromJson(jsonDecode(json) as Map);
- QueryRef ref() {
- return dataConnect.query(this.name, dataDeserializer, null, null);
+ QueryRef ref() {
+ return dataConnect.query(
+ this.name, dataDeserializer, emptySerializer, null);
}
FirebaseDataConnect dataConnect;
@@ -42,10 +43,10 @@ class ListPersonsPeople {
}
}
-class ListPersonsResponse {
+class ListPersonsData {
late List people;
- ListPersonsResponse.fromJson(Map json)
+ ListPersonsData.fromJson(Map json)
: people = (json['people'] as List)
.map((e) => ListPersonsPeople.fromJson(e))
.toList() {}
@@ -59,7 +60,7 @@ class ListPersonsResponse {
return json;
}
- ListPersonsResponse({
+ ListPersonsData({
required this.people,
}) {
// TODO(mtewani): Only show this if there are optional fields.
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart
index 9c0f15b0ac39..cc45dd04c9dd 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/movies.dart
@@ -7,6 +7,8 @@ part 'add_person.dart';
part 'add_director_to_movie.dart';
+part 'seed_data.dart';
+
part 'create_movie.dart';
part 'delete_movie.dart';
@@ -26,6 +28,10 @@ class MoviesConnector {
return AddDirectorToMovie(dataConnect: dataConnect);
}
+ SeedData get seedData {
+ return SeedData(dataConnect: dataConnect);
+ }
+
CreateMovie get createMovie {
return CreateMovie(dataConnect: dataConnect);
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart
new file mode 100644
index 000000000000..26dac17efe67
--- /dev/null
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/generated/seed_data.dart
@@ -0,0 +1,59 @@
+part of movies;
+
+class SeedData {
+ String name = "seedData";
+ SeedData({required this.dataConnect});
+
+ Deserializer dataDeserializer = (String json) =>
+ SeedDataData.fromJson(jsonDecode(json) as Map);
+
+ MutationRef ref() {
+ return dataConnect.mutation(
+ this.name, dataDeserializer, emptySerializer, null);
+ }
+
+ FirebaseDataConnect dataConnect;
+}
+
+class SeedDataMovies1 {
+ late String id;
+
+ SeedDataMovies1.fromJson(Map json) : id = json['id'] {}
+
+ // TODO(mtewani): Fix up to create a map on the fly
+ Map toJson() {
+ Map json = {};
+
+ json['id'] = id;
+
+ return json;
+ }
+
+ SeedDataMovies1({
+ required this.id,
+ }) {
+ // TODO(mtewani): Only show this if there are optional fields.
+ }
+}
+
+class SeedDataData {
+ late SeedDataMovies1 movies1;
+
+ SeedDataData.fromJson(Map json)
+ : movies1 = SeedDataMovies1.fromJson(json['movies1']) {}
+
+ // TODO(mtewani): Fix up to create a map on the fly
+ Map toJson() {
+ Map json = {};
+
+ json['movies1'] = movies1.toJson();
+
+ return json;
+ }
+
+ SeedDataData({
+ required this.movies1,
+ }) {
+ // TODO(mtewani): Only show this if there are optional fields.
+ }
+}
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart b/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart
index 10da1ce05f60..1faa49a538cf 100644
--- a/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/example/lib/main.dart
@@ -109,7 +109,7 @@ class _DataConnectWidgetState extends State {
void initState() {
super.initState();
- QueryRef ref =
+ QueryRef ref =
MoviesConnector.instance.listMovies.ref();
ref.subscribe().listen((event) {
diff --git a/packages/firebase_data_connect/firebase_data_connect/example/test/widget_test.dart b/packages/firebase_data_connect/firebase_data_connect/example/test/widget_test.dart
new file mode 100644
index 000000000000..5ef64fc01675
--- /dev/null
+++ b/packages/firebase_data_connect/firebase_data_connect/example/test/widget_test.dart
@@ -0,0 +1,34 @@
+// Copyright 2024, 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.
+
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility in the flutter_test package. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:firebase_data_connect_example/main.dart';
+
+void main() {
+ testWidgets('Counter increments smoke test', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(const MyApp());
+
+ // Verify that our counter starts at 0.
+ expect(find.text('0'), findsOneWidget);
+ expect(find.text('1'), findsNothing);
+
+ // Tap the '+' icon and trigger a frame.
+ await tester.tap(find.byIcon(Icons.add));
+ await tester.pump();
+
+ // Verify that our counter has incremented.
+ expect(find.text('0'), findsNothing);
+ expect(find.text('1'), findsOneWidget);
+ });
+}
diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/common_library.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/common_library.dart
index c8edc7320221..7c25d77c15a6 100644
--- a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/common_library.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/common_library.dart
@@ -30,7 +30,7 @@ class TransportOptions {
/// Interface for transports connecting to the DataConnect backend.
abstract class DataConnectTransport {
/// Constructor.
- DataConnectTransport(this.transportOptions, this.options);
+ DataConnectTransport(this.transportOptions, this.options, this.appId);
/// Transport options.
TransportOptions transportOptions;
@@ -44,17 +44,20 @@ abstract class DataConnectTransport {
/// FirebaseAppCheck to use to get app check token.
FirebaseAppCheck? appCheck;
+ /// Application ID
+ String appId;
+
/// Invokes corresponding query endpoint.
Future invokeQuery(
String queryName,
Deserializer deserializer,
- Serializer? serializer,
+ Serializer serializer,
Variables? vars);
/// Invokes corresponding mutation endpoint.
Future invokeMutation(
String queryName,
Deserializer deserializer,
- Serializer? serializer,
+ Serializer serializer,
Variables? vars);
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_options.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_options.dart
index 4f55b88cc784..3d23ef63432c 100644
--- a/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_options.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/common/dataconnect_options.dart
@@ -21,9 +21,9 @@ class ConnectorConfig {
/// String representation of connectorConfig
String toJson() {
return jsonEncode({
- 'location': location,
- 'connector': connector,
- 'serviceId': serviceId,
+ location: location,
+ connector: connector,
+ serviceId: serviceId,
});
}
}
diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart
index b68d2069298e..cd693460cfd9 100644
--- a/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/firebase_data_connect.dart
@@ -54,24 +54,19 @@ class FirebaseDataConnect extends FirebasePluginPlatform {
void checkTransport() {
transportOptions ??=
TransportOptions('firebasedataconnect.googleapis.com', null, true);
- transport = getTransport(transportOptions!, options, auth, appCheck);
+ transport = getTransport(
+ transportOptions!, options, app.options.appId, auth, appCheck);
}
/// Returns a [QueryRef] object.
QueryRef query(
String operationName,
Deserializer dataDeserializer,
- Serializer? varsSerializer,
+ Serializer varsSerializer,
Variables? vars) {
checkTransport();
- return QueryRef(
- this,
- operationName,
- transport,
- dataDeserializer,
- _queryManager,
- varsSerializer ?? emptySerializer,
- vars);
+ return QueryRef(this, operationName, transport,
+ dataDeserializer, _queryManager, varsSerializer, vars);
}
/// Returns a [MutationRef] object.
diff --git a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/grpc_transport.dart b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/grpc_transport.dart
index 7b9cf4919232..6fcc25df53c4 100644
--- a/packages/firebase_data_connect/firebase_data_connect/lib/src/network/grpc_transport.dart
+++ b/packages/firebase_data_connect/firebase_data_connect/lib/src/network/grpc_transport.dart
@@ -7,7 +7,13 @@ part of firebase_data_connect_grpc;
/// Transport used for Android/iOS. Uses a GRPC transport instead of REST.
class GRPCTransport implements DataConnectTransport {
/// GRPCTransport creates a new channel
- GRPCTransport(this.transportOptions, this.options, this.auth, this.appCheck) {
+ GRPCTransport(
+ this.transportOptions,
+ this.options,
+ this.appId,
+ this.auth,
+ this.appCheck,
+ ) {
bool isSecure =
transportOptions.isSecure == null || transportOptions.isSecure == true;
channel = ClientChannel(transportOptions.host,
@@ -46,6 +52,10 @@ class GRPCTransport implements DataConnectTransport {
@override
DataConnectOptions options;
+ /// Application ID
+ @override
+ String appId;
+
Future