Skip to content

Commit

Permalink
Simplifies setData extensions (#38)
Browse files Browse the repository at this point in the history
# Simplifies setData extensions

## ♻️ Current situation & Problem
This setData extensions can be simplified to remove the continuations as
the Firebase SDK now provides an async function for saving a dictionary
to Firestore. This may also resolve the bug reported in #37, as the
continuation is now removed.

## ⚙️ Release Notes 
Updates the setData extensions to use the async function as described
above.

## 📚 Documentation
The function signatures are unchanged and no changes to documentation
are required.


## ✅ Testing
Additional tests have been added.


## 📝 Code of Conduct & Contributing Guidelines 

By submitting creating this pull request, you agree to follow our [Code
of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md):
- [X] I agree to follow the [Code of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md).
  • Loading branch information
vishnuravi authored Jul 12, 2024
1 parent 00ff0db commit 67981d0
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 55 deletions.
45 changes: 6 additions & 39 deletions Sources/SpeziFirestore/DocumentReference+AsyncAwait.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,8 @@ extension DocumentReference {
encoder: FirebaseFirestore.Firestore.Encoder = FirebaseFirestore.Firestore.Encoder()
) async throws {
do {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
do {
let encoded = try encoder.encode(value)
setData(encoded) { error in
if let error {
continuation.resume(throwing: error)
}
continuation.resume()
}
} catch {
continuation.resume(throwing: error)
}
}
let encoded = try encoder.encode(value)
try await setData(encoded)
} catch {
throw FirestoreError(error)
}
Expand All @@ -69,19 +58,8 @@ extension DocumentReference {
encoder: FirebaseFirestore.Firestore.Encoder = FirebaseFirestore.Firestore.Encoder()
) async throws {
do {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
do {
let encoded = try encoder.encode(value)
setData(encoded, merge: merge) { error in
if let error {
continuation.resume(throwing: error)
}
continuation.resume()
}
} catch {
continuation.resume(throwing: error)
}
}
let encoded = try encoder.encode(value)
try await setData(encoded, merge: merge)
} catch {
throw FirestoreError(error)
}
Expand Down Expand Up @@ -112,19 +90,8 @@ extension DocumentReference {
encoder: FirebaseFirestore.Firestore.Encoder = FirebaseFirestore.Firestore.Encoder()
) async throws {
do {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
do {
let encoded = try encoder.encode(value)
setData(encoded, mergeFields: mergeFields) { error in
if let error {
continuation.resume(throwing: error)
}
continuation.resume()
}
} catch {
continuation.resume(throwing: error)
}
}
let encoded = try encoder.encode(value)
try await setData(encoded, mergeFields: mergeFields)
} catch {
throw FirestoreError(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,18 @@ struct FirestoreDataStorageTestsView: View {
prompt: Text("Enter the element's identifier.")
)
TextField(
"Context",
"Content",
text: $element.content,
prompt: Text("Enter the element's optional context.")
prompt: Text("Enter the element's optional content.")
)
}
Section("Actions") {
Button("Upload Element") {
uploadElement()
}
Button("Merge Element") {
mergeElement()
}
Button(
role: .destructive,
action: {
Expand All @@ -63,14 +66,39 @@ struct FirestoreDataStorageTestsView: View {
viewState = .processing
Task {
do {
try await Firestore.firestore().collection("Test").document(element.id).setData(from: element)
try await Firestore
.firestore()
.collection("Test")
.document(element.id)
.setData(from: element)
viewState = .idle
} catch {
viewState = .error(FirestoreError(error))
}
}
}

@MainActor
private func mergeElement() {
viewState = .processing
Task {
do {
try await Firestore
.firestore()
.collection("Test")
.document(element.id)
.setData(
from: element,
merge: true
)
viewState = .idle
} catch {
viewState = .error(FirestoreError(error))
}
}
}


@MainActor
private func deleteElement() {
viewState = .processing
Expand Down
55 changes: 42 additions & 13 deletions Tests/UITests/TestAppUITests/FirestoreDataStorageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,31 @@ final class FirestoreDataStorageTests: XCTestCase {
var documents = try await getAllDocuments()
XCTAssert(documents.isEmpty)

try add(id: "Identifier1", context: "1")
try add(id: "Identifier1", content: "1")

try await Task.sleep(for: .seconds(0.5))
documents = try await getAllDocuments()
XCTAssertEqual(
documents.sorted(by: { $0.name < $1.name }),
[
FirestoreElement(
id: "Identifier1",
content: "1"
)
]
)
}

@MainActor
func testFirestoreMerge() async throws {
let app = XCUIApplication()
app.launch()
app.buttons["FirestoreDataStorage"].tap()

var documents = try await getAllDocuments()
XCTAssert(documents.isEmpty)

try merge(id: "Identifier1", content: "1")

try await Task.sleep(for: .seconds(0.5))
documents = try await getAllDocuments()
Expand All @@ -90,7 +114,7 @@ final class FirestoreDataStorageTests: XCTestCase {
var documents = try await getAllDocuments()
XCTAssert(documents.isEmpty)

try add(id: "Identifier1", context: "1")
try add(id: "Identifier1", content: "1")

try await Task.sleep(for: .seconds(0.5))
documents = try await getAllDocuments()
Expand All @@ -104,7 +128,7 @@ final class FirestoreDataStorageTests: XCTestCase {
]
)

try add(id: "Identifier1", context: "2")
try add(id: "Identifier1", content: "2")

try await Task.sleep(for: .seconds(0.5))
documents = try await getAllDocuments()
Expand All @@ -129,7 +153,7 @@ final class FirestoreDataStorageTests: XCTestCase {
var documents = try await getAllDocuments()
XCTAssert(documents.isEmpty)

try add(id: "Identifier1", context: "1")
try add(id: "Identifier1", content: "1")

try await Task.sleep(for: .seconds(0.5))
documents = try await getAllDocuments()
Expand All @@ -143,33 +167,38 @@ final class FirestoreDataStorageTests: XCTestCase {
]
)

try remove(id: "Identifier1", context: "1")
try remove(id: "Identifier1", content: "1")

documents = try await getAllDocuments()
XCTAssert(documents.isEmpty)
}


private func add(id: String, context: String) throws {
try enterFirestoreElement(id: id, context: context)
private func add(id: String, content: String) throws {
try enterFirestoreElement(id: id, content: content)
XCUIApplication().buttons["Upload Element"].tap()
}

private func remove(id: String, context: String) throws {
try enterFirestoreElement(id: id, context: context)
private func merge(id: String, content: String) throws {
try enterFirestoreElement(id: id, content: content)
XCUIApplication().buttons["Merge Element"].tap()
}

private func remove(id: String, content: String) throws {
try enterFirestoreElement(id: id, content: content)
XCUIApplication().buttons["Delete Element"].tap()
}

private func enterFirestoreElement(id: String, context: String) throws {
private func enterFirestoreElement(id: String, content: String) throws {
let app = XCUIApplication()

let identifierTextFieldIdentifier = "Enter the element's identifier."
try app.textFields[identifierTextFieldIdentifier].delete(count: 42)
try app.textFields[identifierTextFieldIdentifier].enter(value: id)

let contextFieldIdentifier = "Enter the element's optional context."
try app.textFields[contextFieldIdentifier].delete(count: 100)
try app.textFields[contextFieldIdentifier].enter(value: context)
let contentFieldIdentifier = "Enter the element's optional content."
try app.textFields[contentFieldIdentifier].delete(count: 100)
try app.textFields[contentFieldIdentifier].enter(value: content)
}

private func deleteAllDocuments() async throws {
Expand Down

0 comments on commit 67981d0

Please sign in to comment.