Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions firebase-dataconnect/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Unreleased

- [changed] Added public APIs for offline caching.
[#7716](https://github.com/firebase/firebase-android-sdk/pull/7716))
- [changed] Added hydration and dehydration logic for use in offline caching.
[#7714](https://github.com/firebase/firebase-android-sdk/pull/7714))
- [changed] Added sqlite database logic for use in offline caching.
[#7720](https://github.com/firebase/firebase-android-sdk/pull/7720))
- [changed] Wired up implementation for serving query responses from cache.
[#7759](https://github.com/firebase/firebase-android-sdk/pull/7759))
- [changed] Internal changes to support future offline caching functionality.
[#7716](https://github.com/firebase/firebase-android-sdk/pull/7716)),
[#7714](https://github.com/firebase/firebase-android-sdk/pull/7714)),
[#7720](https://github.com/firebase/firebase-android-sdk/pull/7720)),
[#7759](https://github.com/firebase/firebase-android-sdk/pull/7759)),
[#NNNN](https://github.com/firebase/firebase-android-sdk/pull/NNNN))

# 17.1.3

Expand Down
33 changes: 0 additions & 33 deletions firebase-dataconnect/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,6 @@ package com.google.firebase.dataconnect {
method public static com.google.firebase.dataconnect.AnyValue? fromNullableAny(com.google.firebase.dataconnect.AnyValue.Companion, Object? value);
}

public final class CacheSettings {
ctor public CacheSettings(com.google.firebase.dataconnect.CacheSettings.Storage storage = com.google.firebase.dataconnect.CacheSettings.Storage.PERSISTENT);
method public com.google.firebase.dataconnect.CacheSettings.Storage getStorage();
property public final com.google.firebase.dataconnect.CacheSettings.Storage storage;
}

public enum CacheSettings.Storage {
enum_constant public static final com.google.firebase.dataconnect.CacheSettings.Storage MEMORY;
enum_constant public static final com.google.firebase.dataconnect.CacheSettings.Storage PERSISTENT;
}

public final class CacheSettingsKt {
method public static com.google.firebase.dataconnect.CacheSettings copy(com.google.firebase.dataconnect.CacheSettings, com.google.firebase.dataconnect.CacheSettings.Storage storage = storage);
}

public final class ConnectorConfig {
ctor public ConnectorConfig(String connector, String location, String serviceId);
method public String getConnector();
Expand Down Expand Up @@ -100,23 +85,14 @@ package com.google.firebase.dataconnect {

public final class DataConnectSettings {
ctor public DataConnectSettings(String host = "firebasedataconnect.googleapis.com", boolean sslEnabled = true);
ctor public DataConnectSettings(String host = "firebasedataconnect.googleapis.com", boolean sslEnabled = true, com.google.firebase.dataconnect.CacheSettings? cacheSettings);
method public com.google.firebase.dataconnect.CacheSettings? getCacheSettings();
method public String getHost();
method public boolean getSslEnabled();
property public final com.google.firebase.dataconnect.CacheSettings? cacheSettings;
property public final String host;
property public final boolean sslEnabled;
}

public final class DataConnectSettingsKt {
method public static com.google.firebase.dataconnect.DataConnectSettings copy(com.google.firebase.dataconnect.DataConnectSettings, String host = host, boolean sslEnabled = sslEnabled);
method public static com.google.firebase.dataconnect.DataConnectSettings copy(com.google.firebase.dataconnect.DataConnectSettings, String host = host, boolean sslEnabled = sslEnabled, com.google.firebase.dataconnect.CacheSettings? cacheSettings);
}

public enum DataSource {
enum_constant public static final com.google.firebase.dataconnect.DataSource CACHE;
enum_constant public static final com.google.firebase.dataconnect.DataSource SERVER;
}

public sealed interface EnumValue<T extends java.lang.Enum<? extends T>> {
Expand Down Expand Up @@ -304,23 +280,14 @@ package com.google.firebase.dataconnect {

public interface QueryRef<Data, Variables> extends com.google.firebase.dataconnect.OperationRef<Data,Variables> {
method @com.google.firebase.dataconnect.ExperimentalFirebaseDataConnect public com.google.firebase.dataconnect.QueryRef<Data,Variables> copy(String operationName, Variables variables, kotlinx.serialization.DeserializationStrategy<? extends Data> dataDeserializer, kotlinx.serialization.SerializationStrategy<? super Variables> variablesSerializer, com.google.firebase.dataconnect.FirebaseDataConnect.CallerSdkType callerSdkType, kotlinx.serialization.modules.SerializersModule? dataSerializersModule, kotlinx.serialization.modules.SerializersModule? variablesSerializersModule);
method public suspend Object? execute(com.google.firebase.dataconnect.QueryRef.FetchPolicy fetchPolicy, kotlin.coroutines.Continuation<? super com.google.firebase.dataconnect.QueryResult<Data,Variables>>);
method public suspend Object? execute(kotlin.coroutines.Continuation<? super com.google.firebase.dataconnect.QueryResult<Data,Variables>>);
method public com.google.firebase.dataconnect.QuerySubscription<Data,Variables> subscribe();
method @com.google.firebase.dataconnect.ExperimentalFirebaseDataConnect public <NewData> com.google.firebase.dataconnect.QueryRef<NewData,Variables> withDataDeserializer(kotlinx.serialization.DeserializationStrategy<? extends NewData> dataDeserializer, kotlinx.serialization.modules.SerializersModule? dataSerializersModule);
method @com.google.firebase.dataconnect.ExperimentalFirebaseDataConnect public <NewVariables> com.google.firebase.dataconnect.QueryRef<Data,NewVariables> withVariablesSerializer(NewVariables variables, kotlinx.serialization.SerializationStrategy<? super NewVariables> variablesSerializer, kotlinx.serialization.modules.SerializersModule? variablesSerializersModule);
}

public enum QueryRef.FetchPolicy {
enum_constant public static final com.google.firebase.dataconnect.QueryRef.FetchPolicy CACHE_ONLY;
enum_constant public static final com.google.firebase.dataconnect.QueryRef.FetchPolicy PREFER_CACHE;
enum_constant public static final com.google.firebase.dataconnect.QueryRef.FetchPolicy SERVER_ONLY;
}

public interface QueryResult<Data, Variables> extends com.google.firebase.dataconnect.OperationResult<Data,Variables> {
method public com.google.firebase.dataconnect.DataSource getDataSource();
method public com.google.firebase.dataconnect.QueryRef<Data,Variables> getRef();
property public abstract com.google.firebase.dataconnect.DataSource dataSource;
property public abstract com.google.firebase.dataconnect.QueryRef<Data,Variables> ref;
}

Expand Down
2 changes: 1 addition & 1 deletion firebase-dataconnect/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=17.2.0
version=17.1.4
latestReleasedVersion=17.1.3
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import java.util.Objects
*
* @property storage The type of storage to use to store the cache data.
*/
public class CacheSettings(
public val storage: Storage = Storage.PERSISTENT,
// TODO: make public when offline caching goes public
internal class CacheSettings(
val storage: Storage = Storage.PERSISTENT,
) {

/**
* The types of cache storage supported by [FirebaseDataConnect] in its [CacheSettings] setting.
*/
public enum class Storage {
enum class Storage {
MEMORY,
PERSISTENT,
}
Expand Down Expand Up @@ -66,14 +67,15 @@ public class CacheSettings(
* changes.
*
* @return a string representation of this object, which includes the class name and the values of
* all public properties.
* all properties.
*/
override fun toString(): String {
return "CacheSettings(storage=$storage)"
}
}

/** Creates and returns a new [CacheSettings] object with the given property values. */
public fun CacheSettings.copy(
// TODO: make public when offline caching goes public
internal fun CacheSettings.copy(
storage: CacheSettings.Storage = this.storage,
): CacheSettings = CacheSettings(storage = storage)
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,12 @@ import java.util.Objects
* @property sslEnabled Whether to use SSL for the connection; if `true`, then the connection will
* be encrypted using SSL and, if false, the connection will _not_ be encrypted and all network
* transmission will happen in plaintext.
* @property cacheSettings The local caching settings; if `null` then do not perform any local
* caching.
*/
public class DataConnectSettings(
public val host: String = "firebasedataconnect.googleapis.com",
public val sslEnabled: Boolean = true,
public val cacheSettings: CacheSettings?,
public val sslEnabled: Boolean = true
) {

// TODO(BreakingChange): Delete this constructor and set the default value for `cacheSettings`
// in the primary constructor.
public constructor(
host: String = "firebasedataconnect.googleapis.com",
sslEnabled: Boolean = true,
) : this(host = host, sslEnabled = sslEnabled, cacheSettings = null)

/**
* Compares this object with another object for equality.
*
Expand All @@ -56,10 +46,7 @@ public class DataConnectSettings(
* object.
*/
override fun equals(other: Any?): Boolean =
(other is DataConnectSettings) &&
other.host == host &&
other.sslEnabled == sslEnabled &&
other.cacheSettings == cacheSettings
(other is DataConnectSettings) && other.host == host && other.sslEnabled == sslEnabled

/**
* Calculates and returns the hash code for this object.
Expand All @@ -69,8 +56,7 @@ public class DataConnectSettings(
* @return the hash code for this object, that incorporates the values of this object's public
* properties.
*/
override fun hashCode(): Int =
Objects.hash(DataConnectSettings::class, host, sslEnabled, cacheSettings)
override fun hashCode(): Int = Objects.hash(DataConnectSettings::class, host, sslEnabled)

/**
* Returns a string representation of this object, useful for debugging.
Expand All @@ -84,25 +70,13 @@ public class DataConnectSettings(
* @return a string representation of this object, which includes the class name and the values of
* all public properties.
*/
override fun toString(): String =
"DataConnectSettings(host=$host, sslEnabled=$sslEnabled, cacheSettings=$cacheSettings)"
override fun toString(): String = "DataConnectSettings(host=$host, sslEnabled=$sslEnabled)"
}

/** Creates and returns a new [DataConnectSettings] instance with the given property values. */
// TODO(BreakingChange): Delete this method and set the default value for `cacheSettings` in the
// remaining copy() method.
public fun DataConnectSettings.copy(
host: String = this.host,
sslEnabled: Boolean = this.sslEnabled,
): DataConnectSettings =
DataConnectSettings(host = host, sslEnabled = sslEnabled, cacheSettings = cacheSettings)

/** Creates and returns a new [DataConnectSettings] instance with the given property values. */
public fun DataConnectSettings.copy(
host: String = this.host,
sslEnabled: Boolean = this.sslEnabled,
cacheSettings: CacheSettings?,
): DataConnectSettings =
DataConnectSettings(host = host, sslEnabled = sslEnabled, cacheSettings = cacheSettings)
sslEnabled: Boolean = this.sslEnabled
): DataConnectSettings = DataConnectSettings(host = host, sslEnabled = sslEnabled)

internal fun DataConnectSettings.isDefaultHost() = host == DataConnectSettings().host
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,7 @@ import kotlinx.serialization.modules.SerializersModule
* might be added to this interface or contracts of the existing methods can be changed.
*/
public interface QueryRef<Data, Variables> : OperationRef<Data, Variables> {

/**
* Executes this operation with the fetch policy [FetchPolicy.PREFER_CACHE] and returns the
* result.
*/
// TODO(BreakingChange) Implement the method here to call execute(PREFER_CACHE) instead of
// having QueryRefImpl do it.
public override suspend fun execute(): QueryResult<Data, Variables>

/** Executes this operation with the given fetch policy, and returns the result. */
public suspend fun execute(fetchPolicy: FetchPolicy): QueryResult<Data, Variables>

/** The caching policy to use in [QueryRef.execute]. */
public enum class FetchPolicy {

/**
* If the query has a cached result that has not expired, then return it without any
* communication with the server, just as [CACHE_ONLY] would do. Otherwise, if there is no
* cached data for the query or the cached data has expired, then get the latest result from the
* server, just as [SERVER_ONLY] would do.
*/
PREFER_CACHE,

/**
* Return the query result from the cache without any communication with the server. If there is
* no cached data for the query then return an empty/null result, just as the server would have
* returned in that case.
*/
CACHE_ONLY,

/**
* Unconditionally get the latest result from the server, even if there is a locally-cached
* result for the query. The local cache will be updated with the result, if successful.
*/
SERVER_ONLY,
}
override suspend fun execute(): QueryResult<Data, Variables>

/**
* Subscribes to a query to be notified of updates to the query's data when the query is executed.
Expand Down Expand Up @@ -122,13 +87,4 @@ public interface QueryRef<Data, Variables> : OperationRef<Data, Variables> {
*/
public interface QueryResult<Data, Variables> : OperationResult<Data, Variables> {
override val ref: QueryRef<Data, Variables>

/** The source of the query results provided by this object. */
public val dataSource: DataSource
}

/** Indicator of the source of a query's results. */
public enum class DataSource {
CACHE,
SERVER,
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import android.content.Context
import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider
import com.google.firebase.auth.internal.InternalAuthProvider
import com.google.firebase.dataconnect.CacheSettings
import com.google.firebase.dataconnect.ConnectorConfig
import com.google.firebase.dataconnect.DataConnectSettings
import com.google.firebase.dataconnect.FirebaseDataConnect
Expand Down Expand Up @@ -240,19 +239,6 @@ internal class FirebaseDataConnectImpl(
backendInfoFromEmulatorSettings
}

val cacheSettings =
settings.cacheSettings?.run {
val dbFile =
when (storage) {
CacheSettings.Storage.MEMORY -> null
CacheSettings.Storage.PERSISTENT -> {
val dbName = "dataconnect_" + calculateCacheDbUniqueName(backendInfo)
context.getDatabasePath(dbName)
}
}
DataConnectGrpcRPCs.CacheSettings(dbFile)
}

logger.debug { "connecting to Data Connect backend: $backendInfo" }
val grpcMetadata =
DataConnectGrpcMetadata.forSystemVersions(
Expand All @@ -269,7 +255,7 @@ internal class FirebaseDataConnectImpl(
sslEnabled = backendInfo.sslEnabled,
blockingCoroutineDispatcher = blockingDispatcher,
grpcMetadata = grpcMetadata,
cacheSettings = cacheSettings,
cacheSettings = null, // TODO: pass cache settings once implemented
parentLogger = logger,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@

package com.google.firebase.dataconnect.core

import com.google.firebase.dataconnect.DataSource
import com.google.firebase.dataconnect.FirebaseDataConnect
import com.google.firebase.dataconnect.QueryRef
import com.google.firebase.dataconnect.QueryRef.FetchPolicy
import com.google.firebase.dataconnect.QueryResult
import com.google.firebase.dataconnect.QuerySubscription
import java.util.Objects
Expand Down Expand Up @@ -50,12 +48,8 @@ internal class QueryRefImpl<Data, Variables>(
dataSerializersModule = dataSerializersModule,
variablesSerializersModule = variablesSerializersModule,
) {
override suspend fun execute(): QueryResultImpl = execute(FetchPolicy.PREFER_CACHE)

override suspend fun execute(fetchPolicy: FetchPolicy): QueryResultImpl =
dataConnect.queryManager.execute(this).let {
QueryResultImpl(it.ref.getOrThrow(), DataSource.SERVER)
}
override suspend fun execute(): QueryResultImpl =
dataConnect.queryManager.execute(this).let { QueryResultImpl(it.ref.getOrThrow()) }

override fun subscribe(): QuerySubscription<Data, Variables> = QuerySubscriptionImpl(this)

Expand Down Expand Up @@ -140,18 +134,16 @@ internal class QueryRefImpl<Data, Variables>(
"variablesSerializersModule=$variablesSerializersModule" +
")"

inner class QueryResultImpl(data: Data, override val dataSource: DataSource) :
inner class QueryResultImpl(data: Data) :
QueryResult<Data, Variables>, OperationRefImpl<Data, Variables>.OperationResultImpl(data) {

override val ref = this@QueryRefImpl

override fun equals(other: Any?) =
other is QueryRefImpl<*, *>.QueryResultImpl &&
super.equals(other) &&
other.dataSource == dataSource
other is QueryRefImpl<*, *>.QueryResultImpl && super.equals(other)

override fun hashCode() = Objects.hash(QueryResultImpl::class, data, ref, dataSource)
override fun hashCode() = Objects.hash(QueryResultImpl::class, data, ref)

override fun toString() = "QueryResultImpl(data=$data, ref=$ref, dataSource=$dataSource)"
override fun toString() = "QueryResultImpl(data=$data, ref=$ref)"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package com.google.firebase.dataconnect.core

import com.google.firebase.dataconnect.DataSource
import com.google.firebase.dataconnect.QuerySubscriptionResult
import com.google.firebase.dataconnect.util.NullableReference
import com.google.firebase.dataconnect.util.SequencedReference
Expand Down Expand Up @@ -107,7 +106,7 @@ internal class QuerySubscriptionImpl<Data, Variables>(query: QueryRefImpl<Data,
override val query: QueryRefImpl<Data, Variables>,
val sequencedResult: SequencedReference<Result<Data>>
) : QuerySubscriptionResult<Data, Variables> {
override val result = sequencedResult.ref.map { query.QueryResultImpl(it, DataSource.SERVER) }
override val result = sequencedResult.ref.map { query.QueryResultImpl(it) }

override fun equals(other: Any?) =
other is QuerySubscriptionImpl<*, *>.QuerySubscriptionResultImpl &&
Expand Down
Loading
Loading