-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDatabaseAccessExample_01.swift
More file actions
171 lines (142 loc) · 6.88 KB
/
Copy pathDatabaseAccessExample_01.swift
File metadata and controls
171 lines (142 loc) · 6.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
Code by Ethan Palosh for the iOS App "Detailer"
DatabaseAccessExample_01 - Firebase Firestore
This file contains some sample high-level database access functions. They are implemented in the app code.
- This class specifically accesses data in the Firebase Firestore database.
Published for portfolio purposes only.
*/
class FirestoreService {
static let shared = FirestoreService()
private init() {}
let db = Firestore.firestore()
// function to save user data to the database. Used when creating a new account.
func saveUserData(userId: String, data: [String: Any], completion: @escaping (Result<Void, Error>) -> Void) {
db.collection("user-data").document(userId).setData(data) { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}
// function to save the user's email to the usersByEmail dictionary in the database
func saveUserWithEmailAsID(email: String, uid: String, completion: @escaping (Result<Void, Error>) -> Void) {
let data = ["email": email, "uid": uid]
db.collection("usersByEmail").document(email).setData(data) { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}
// function to retrive user-data on the current user. Used in fetchUserData, which is called at launch
func getUserData(userId: String, completion: @escaping (Result<[String: Any], Error>) -> Void) {
db.collection("user-data").document(userId).getDocument { document, error in
if let document = document, document.exists {
if let data = document.data() {
completion(.success(data))
} else {
completion(.failure(NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "No data found"])))
}
} else {
completion(.failure(error ?? NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "Document does not exist"])))
}
}
}
// database call to update the user's data from the settings menu UI
func updateUserData(userId: String, data: [String: Any], completion: @escaping (Result<Void, Error>) -> Void) {
let userRef = db.collection("user-data").document(userId)
// Update the document with the new data
userRef.updateData(data) { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}
// Function to delete user data from Firestore
func deleteUserData(userId: String, completion: @escaping (Result<Void, Error>) -> Void) {
let db = Firestore.firestore()
// Reference to the user's document in "user-data" collection
let userDocRef = db.collection("user-data").document(userId)
// Delete all messages in the "messages" subcollection
userDocRef.collection("messages").getDocuments { (querySnapshot, error) in
if let error = error {
completion(.failure(error))
return
}
let batch = db.batch()
for document in querySnapshot?.documents ?? [] {
batch.deleteDocument(document.reference)
}
batch.commit { error in
if let error = error {
completion(.failure(error))
return
}
// Delete the user document itself
userDocRef.delete { error in
if let error = error {
completion(.failure(error))
return
}
// Delete from "emailToUID" collection
db.collection("emailToUID").whereField("uid", isEqualTo: userId).getDocuments { querySnapshot, error in
if let error = error {
completion(.failure(error))
return
}
let batch = db.batch()
for document in querySnapshot?.documents ?? [] {
batch.deleteDocument(document.reference)
}
batch.commit { error in
if let error = error {
completion(.failure(error))
return
}
// Now delete from "usersByEmail" collection
db.collection("usersByEmail").whereField("uid", isEqualTo: userId).getDocuments { querySnapshot, error in
if let error = error {
completion(.failure(error))
return
}
let batch = db.batch()
for document in querySnapshot?.documents ?? [] {
batch.deleteDocument(document.reference)
}
batch.commit { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}
}
}
}
}
}
}
func getAPIKey(completion: @escaping (String?, Error?) -> Void) {
let db = Firestore.firestore()
let docRef = db.collection("config").document("apiKey")
docRef.getDocument { document, error in
if let error = error {
print("Error getting document: \(error)")
completion(nil, error)
} else if let document = document, document.exists {
if let apiKey = document.data()?["key"] as? String {
completion(apiKey, nil)
} else {
completion(nil, NSError(domain: "AppErrorDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "API key not found"]))
}
} else {
completion(nil, NSError(domain: "AppErrorDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "Document not found"]))
}
}
}
} // End FireStoreService