This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class StateHolder<T : Any>(state: T) { | |
private val _liveData = MutableLiveData(state) | |
val liveData: LiveData<T> get() = _liveData | |
private var _value: T = state | |
val value: T get() = _value | |
fun update(notify: Boolean = true, block: T.() -> T) { | |
synchronized(LOCK) { | |
_value = block(value) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Keep | |
internal class LoggingHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler), | |
CoroutineExceptionHandler { | |
override fun handleException(context: CoroutineContext, exception: Throwable) { | |
Crashlytics.logException(exception) | |
// Since we don't want to crash and Coroutines will call the current thread's handler, we | |
// install a noop handler and then reinstall the existing one once coroutines calls the new | |
// handler. | |
Thread.currentThread().apply { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public suspend inline fun <T : Closeable?, R> T.useCancellably( | |
crossinline block: (T) -> R | |
): R = suspendCancellableCoroutine { cont -> | |
cont.invokeOnCancellation { this?.close() } | |
cont.resume(use(block)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
infix fun <T> Boolean.q(primary: T) = if (this) Ternary(primary) else null | |
infix fun <T> Ternary<T>?.e(other: T) = if (this == null) other else result | |
data class Ternary<T>(internal val result: T) | |
val bool = true | |
println(bool q "true" e "false") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend fun <T> Task<T>.await(): T { | |
if (isComplete) return if (isSuccessful) result else throw exception!! | |
return suspendCoroutine { c: Continuation<T> -> | |
addOnSuccessListener { c.resume(it) } | |
addOnFailureListener { c.resumeWithException(it) } | |
} | |
} | |
fun <T> Deferred<T>.asTask(): Task<T> { | |
val source = TaskCompletionSource<T>() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.SuppressLint | |
import android.os.Bundle | |
import android.os.Parcelable | |
import android.support.v4.app.Fragment | |
import android.support.v4.app.FragmentManager | |
import android.support.v4.app.FragmentTransaction | |
import android.view.View | |
import android.view.ViewGroup | |
import java.util.HashSet | |
import java.util.LinkedHashMap |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
service cloud.firestore { | |
match /databases/{database}/documents { | |
// Incorrect solution | |
match /public/{doc=**} { | |
allow read; | |
match /foo/{bar} { | |
allow write: if doc == "foobar"; // Error! "doc" is a path object, not a string | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
service cloud.firestore { | |
match /databases/{database}/documents { | |
// Incorrect solution | |
match /teams/{teamId} { | |
allow read: ...; | |
allow write: if request.resource.data.owners[request.auth.uid] is int // Returns false on delete! | |
&& isValidTeam(); | |
} | |
// Correct solution |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
service cloud.firestore { // Boilerplate! | |
match /databases/{database}/documents { // More boilerplate. | |
match /{document=**} { | |
allow read, write; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Creating tables for v1 | |
db.execSQL("CREATE TABLE mutation_queues (uid TEXT PRIMARY KEY, last_acknowledged_batch_id INTEGER, last_stream_token BLOB)"); | |
db.execSQL("CREATE TABLE mutations (uid TEXT, batch_id INTEGER, mutations BLOB, PRIMARY KEY (uid, batch_id))"); | |
db.execSQL("CREATE TABLE document_mutations (uid TEXT, path TEXT, batch_id INTEGER, PRIMARY KEY (uid, path, batch_id))"); | |
db.execSQL("CREATE TABLE targets (target_id INTEGER PRIMARY KEY, canonical_id TEXT, snapshot_version_seconds INTEGER, snapshot_version_nanos INTEGER, resume_token BLOB, last_listen_sequence_number INTEGER,target_proto BLOB)"); | |
db.execSQL("CREATE INDEX query_targets ON targets (canonical_id, target_id)"); | |
db.execSQL("CREATE TABLE target_globals (highest_target_id INTEGER, highest_listen_sequence_number INTEGER)"); | |
db.execSQL("CREATE TABLE target_documents (target_id INTEGER, path TEXT, PRIMARY KEY (target_id, path))"); | |
db.execSQL("CREATE INDEX document_targets ON target_documents (path, target_id)"); | |
db.execSQL("CREATE TABLE remot |
NewerOlder