aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Swift/Tests/API
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Swift/Tests/API')
-rw-r--r--Firestore/Swift/Tests/API/BasicCompileTests.swift420
1 files changed, 420 insertions, 0 deletions
diff --git a/Firestore/Swift/Tests/API/BasicCompileTests.swift b/Firestore/Swift/Tests/API/BasicCompileTests.swift
new file mode 100644
index 0000000..16886e2
--- /dev/null
+++ b/Firestore/Swift/Tests/API/BasicCompileTests.swift
@@ -0,0 +1,420 @@
+/*
+ * Copyright 2017 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// These aren't tests in the usual sense--they just verify that the Objective-C to Swift translation
+// results in the right names.
+
+import Foundation
+import XCTest
+import FirebaseFirestore
+
+class BasicCompileTests: XCTestCase {
+ func testCompiled() {
+ XCTAssertTrue(true)
+ }
+}
+
+func main() {
+ let db = initializeDb()
+
+ let (collectionRef, documentRef) = makeRefs(database: db)
+
+ let query = makeQuery(collection: collectionRef)
+
+ writeDocument(at: documentRef)
+
+ writeDocuments(at: documentRef, database: db)
+
+ addDocument(to: collectionRef)
+
+ readDocument(at: documentRef)
+ readDocumentWithSource(at: documentRef)
+
+ readDocuments(matching: query)
+ readDocumentsWithSource(matching: query)
+
+ listenToDocument(at: documentRef)
+
+ listenToDocuments(matching: query)
+
+ enableDisableNetwork(database: db)
+
+ types()
+}
+
+func initializeDb() -> Firestore {
+ // Initialize with ProjectID.
+ let firestore = Firestore.firestore()
+
+ // Apply settings
+ let settings = FirestoreSettings()
+ settings.host = "localhost"
+ settings.isPersistenceEnabled = true
+ settings.areTimestampsInSnapshotsEnabled = true
+ firestore.settings = settings
+
+ return firestore
+}
+
+func makeRefs(database db: Firestore) -> (CollectionReference, DocumentReference) {
+ var collectionRef = db.collection("my-collection")
+
+ var documentRef: DocumentReference
+ documentRef = collectionRef.document("my-doc")
+ // or
+ documentRef = db.document("my-collection/my-doc")
+
+ // deeper collection (my-collection/my-doc/some/deep/collection)
+ collectionRef = documentRef.collection("some/deep/collection")
+
+ // parent doc (my-collection/my-doc/some/deep)
+ documentRef = collectionRef.parent!
+
+ // print paths.
+ print("Collection: \(collectionRef.path), document: \(documentRef.path)")
+
+ return (collectionRef, documentRef)
+}
+
+func makeQuery(collection collectionRef: CollectionReference) -> Query {
+ let query = collectionRef.whereField(FieldPath(["name"]), isEqualTo: "Fred")
+ .whereField("age", isGreaterThanOrEqualTo: 24)
+ .whereField("tags", arrayContains: "active")
+ .whereField(FieldPath(["tags"]), arrayContains: "active")
+ .whereField(FieldPath.documentID(), isEqualTo: "fred")
+ .order(by: FieldPath(["age"]))
+ .order(by: "name", descending: true)
+ .limit(to: 10)
+
+ return query
+}
+
+func writeDocument(at docRef: DocumentReference) {
+ let setData = [
+ "foo": 42,
+ "bar": [
+ "baz": "Hello world!",
+ ],
+ ] as [String: Any]
+
+ let updateData = [
+ "bar.baz": 42,
+ FieldPath(["foobar"]): 42,
+ "server_timestamp": FieldValue.serverTimestamp(),
+ "array_union": FieldValue.arrayUnion(["a", "b"]),
+ "array_remove": FieldValue.arrayRemove(["a", "b"]),
+ "field_delete": FieldValue.delete(),
+ ] as [AnyHashable: Any]
+
+ docRef.setData(setData)
+
+ // Completion callback (via trailing closure syntax).
+ docRef.setData(setData) { error in
+ if let error = error {
+ print("Uh oh! \(error)")
+ return
+ }
+
+ print("Set complete!")
+ }
+
+ // merge
+ docRef.setData(setData, merge: true)
+ docRef.setData(setData, merge: true) { error in
+ if let error = error {
+ print("Uh oh! \(error)")
+ return
+ }
+
+ print("Set complete!")
+ }
+
+ docRef.updateData(updateData)
+ docRef.delete()
+
+ docRef.delete { error in
+ if let error = error {
+ print("Uh oh! \(error)")
+ return
+ }
+
+ print("Set complete!")
+ }
+}
+
+func enableDisableNetwork(database db: Firestore) {
+ // closure syntax
+ db.disableNetwork(completion: { error in
+ if let e = error {
+ print("Uh oh! \(e)")
+ return
+ }
+ })
+ // trailing block syntax
+ db.enableNetwork { error in
+ if let e = error {
+ print("Uh oh! \(e)")
+ return
+ }
+ }
+}
+
+func writeDocuments(at docRef: DocumentReference, database db: Firestore) {
+ var batch: WriteBatch
+
+ batch = db.batch()
+ batch.setData(["a": "b"], forDocument: docRef)
+ batch.setData(["a": "b"], forDocument: docRef, merge: true)
+ batch.setData(["c": "d"], forDocument: docRef)
+ // commit without completion callback.
+ batch.commit()
+ print("Batch write without completion complete!")
+
+ batch = db.batch()
+ batch.setData(["a": "b"], forDocument: docRef)
+ batch.setData(["c": "d"], forDocument: docRef)
+ // commit with completion callback via trailing closure syntax.
+ batch.commit { error in
+ if let error = error {
+ print("Uh oh! \(error)")
+ return
+ }
+ print("Batch write callback complete!")
+ }
+ print("Batch write with completion complete!")
+}
+
+func addDocument(to collectionRef: CollectionReference) {
+ collectionRef.addDocument(data: ["foo": 42])
+ // or
+ collectionRef.document().setData(["foo": 42])
+}
+
+func readDocument(at docRef: DocumentReference) {
+ // Trailing closure syntax.
+ docRef.getDocument { document, error in
+ if let document = document {
+ // Note that both document and document.data() is nullable.
+ if let data = document.data() {
+ print("Read document: \(data)")
+ }
+ if let data = document.data(with: .estimate) {
+ print("Read document: \(data)")
+ }
+ if let foo = document.get("foo") {
+ print("Field: \(foo)")
+ }
+ if let foo = document.get("foo", serverTimestampBehavior: .previous) {
+ print("Field: \(foo)")
+ }
+ // Fields can also be read via subscript notation.
+ if let foo = document["foo"] {
+ print("Field: \(foo)")
+ }
+ } else {
+ // TODO(mikelehen): There may be a better way to do this, but it at least demonstrates
+ // the swift error domain / enum codes are renamed appropriately.
+ if let errorCode = error.flatMap({
+ ($0._domain == FirestoreErrorDomain) ? FirestoreErrorCode(rawValue: $0._code) : nil
+ }) {
+ switch errorCode {
+ case .unavailable:
+ print("Can't read document due to being offline!")
+ case _:
+ print("Failed to read.")
+ }
+ } else {
+ print("Unknown error!")
+ }
+ }
+ }
+}
+
+func readDocumentWithSource(at docRef: DocumentReference) {
+ docRef.getDocument(source: FirestoreSource.default) { document, error in
+ }
+ docRef.getDocument(source: .server) { document, error in
+ }
+ docRef.getDocument(source: FirestoreSource.cache) { document, error in
+ }
+}
+
+func readDocuments(matching query: Query) {
+ query.getDocuments { querySnapshot, error in
+ // TODO(mikelehen): Figure out how to make "for..in" syntax work
+ // directly on documentSet.
+ for document in querySnapshot!.documents {
+ print(document.data())
+ }
+ }
+}
+
+func readDocumentsWithSource(matching query: Query) {
+ query.getDocuments(source: FirestoreSource.default) { querySnapshot, error in
+ }
+ query.getDocuments(source: .server) { querySnapshot, error in
+ }
+ query.getDocuments(source: FirestoreSource.cache) { querySnapshot, error in
+ }
+}
+
+func listenToDocument(at docRef: DocumentReference) {
+ let listener = docRef.addSnapshotListener { document, error in
+ if let error = error {
+ print("Uh oh! Listen canceled: \(error)")
+ return
+ }
+
+ if let document = document {
+ // Note that document.data() is nullable.
+ if let data: [String: Any] = document.data() {
+ print("Current document: \(data)")
+ }
+ if document.metadata.isFromCache {
+ print("From Cache")
+ } else {
+ print("From Server")
+ }
+ }
+ }
+
+ // Unsubscribe.
+ listener.remove()
+}
+
+func listenToDocumentWithMetadataChanges(at docRef: DocumentReference) {
+ let listener = docRef.addSnapshotListener(includeMetadataChanges: true) { document, error in
+ if let document = document {
+ if document.metadata.hasPendingWrites {
+ print("Has pending writes")
+ }
+ }
+ }
+
+ // Unsubscribe.
+ listener.remove()
+}
+
+func listenToDocuments(matching query: Query) {
+ let listener = query.addSnapshotListener { snap, error in
+ if let error = error {
+ print("Uh oh! Listen canceled: \(error)")
+ return
+ }
+
+ if let snap = snap {
+ print("NEW SNAPSHOT (empty=\(snap.isEmpty) count=\(snap.count)")
+
+ // TODO(mikelehen): Figure out how to make "for..in" syntax work
+ // directly on documentSet.
+ for document in snap.documents {
+ // Note that document.data() is not nullable.
+ let data: [String: Any] = document.data()
+ print("Doc: ", data)
+ }
+ }
+ }
+
+ // Unsubscribe
+ listener.remove()
+}
+
+func listenToQueryDiffs(onQuery query: Query) {
+ let listener = query.addSnapshotListener { snap, error in
+ if let snap = snap {
+ for change in snap.documentChanges {
+ switch change.type {
+ case .added:
+ print("New document: \(change.document.data())")
+ case .modified:
+ print("Modified document: \(change.document.data())")
+ case .removed:
+ print("Removed document: \(change.document.data())")
+ }
+ }
+ }
+ }
+
+ // Unsubscribe
+ listener.remove()
+}
+
+func listenToQueryDiffsWithMetadata(onQuery query: Query) {
+ let listener = query.addSnapshotListener(includeMetadataChanges: true) { snap, error in
+ if let snap = snap {
+ for change in snap.documentChanges(includeMetadataChanges: true) {
+ switch change.type {
+ case .added:
+ print("New document: \(change.document.data())")
+ case .modified:
+ print("Modified document: \(change.document.data())")
+ case .removed:
+ print("Removed document: \(change.document.data())")
+ }
+ }
+ }
+ }
+
+ // Unsubscribe
+ listener.remove()
+}
+
+func transactions() {
+ let db = Firestore.firestore()
+
+ let collectionRef = db.collection("cities")
+ let accA = collectionRef.document("accountA")
+ let accB = collectionRef.document("accountB")
+ let amount = 20.0
+
+ db.runTransaction({ (transaction, errorPointer) -> Any? in
+ do {
+ let balanceA = try transaction.getDocument(accA)["balance"] as! Double
+ let balanceB = try transaction.getDocument(accB)["balance"] as! Double
+
+ if balanceA < amount {
+ errorPointer?.pointee = NSError(domain: "Foo", code: 123, userInfo: nil)
+ return nil
+ }
+ transaction.updateData(["balance": balanceA - amount], forDocument: accA)
+ transaction.updateData(["balance": balanceB + amount], forDocument: accB)
+ } catch let error as NSError {
+ print("Uh oh! \(error)")
+ }
+ return 0
+ }) { result, error in
+ // handle result.
+ }
+}
+
+func types() {
+ let _: CollectionReference
+ let _: DocumentChange
+ let _: DocumentReference
+ let _: DocumentSnapshot
+ let _: FieldPath
+ let _: FieldValue
+ let _: Firestore
+ let _: FirestoreSettings
+ let _: GeoPoint
+ let _: Timestamp
+ let _: ListenerRegistration
+ let _: Query
+ let _: QuerySnapshot
+ let _: SnapshotMetadata
+ let _: Transaction
+ let _: WriteBatch
+}