如何避免 firestore 中的重复文件?
How to avoid dup documents in firestore?
我正在尝试检查 FB 事件是否已作为文档存在于我的 Firestore 集合中,如果不存在,则将新的 FB 事件作为新文档写入。我的问题是,当将解析的图形请求 'results' 字典与我集合中的 fbEventIds 进行比较时,逻辑设置不正确并创建重复而不是避免它们。
逻辑上我的功能是如何设置的:
func getFbEvents {
fbgraphrequest {
parse graphrequest results into an Event object {
get Firestore snapshot of 'events' collection {
//Compare graph request event id to event ids stored in firestore
if graphrequesteventId == FirestoresnapshoteventsFbId {
return
}
else {
setdata of new fb event in firestore events collection
}}}}}
实际代码
我已经尝试在解析字典之后和基于其他 SO 线程检索快照之前添加 DispatchGroup 和 DispatchQueue enter 和 leave 命令,但它仍然不适用于我的代码。
static func getFBEvents() {
let graphRequest : GraphRequest = GraphRequest(graphPath: "/me", parameters: ["fields":"id, events"], httpMethod: .get)
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
}
else {
if let dictionary = result as? [String: Any] {
if let dictionary1 = dictionary["events"] as? [String: Any]{
if let dataList = dictionary1["data"] as? [[String: Any]] {
dataList.forEach { dictionary in
let eventDescription = dictionary["description"] as? String
let fbEventId = dictionary["id"] as? String
let eventName = dictionary["name"] as? String
let eventStart = dictionary["start_time"] as? String
if let nestedDictionary = dictionary["place"] as? [String: Any] {
let eventLocation = nestedDictionary["name"] as? String
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("events").getDocuments() { (querySnapshot, err) in
if let err = err {
return
}
else {
for doc in querySnapshot!.documents {
let e = Event(snapshot: doc)
print("fb eventId: \(e?.fbEventId) & \(fbEventId)")
if e!.fbEventId != fbEventId {
print("event does not already exists, writing event to Firestore")
let newDocument = Firestore.firestore().collection("events").document()
//Create a dictionary for the event
let eventData = ["eventDescription":eventDescription, "eventStart":eventStart,"fbEventId": fbEventId, "eventCreated": Timestamp(date: Date()), "eventId": newDocument.documentID, "eventName": eventName, "eventSource": "FB", "eventLocation": eventLocation] as [String : Any]
//Create the profile for the event
newDocument.setData(eventData) { (error) in
if error != nil {
}
else {
}
}//close Firestore setData
}
else {
return
}
}
}
}//close retrieve events
}//close nested Dictionfary for place
}//close datalist for each
}//close datalist
}//close dictionary1
}//close dictionary
}//close else
}//close graph request start
)}//close getFBEvents
}
经过更多的挖掘,我想我得到了我需要的东西。如果您认为这不会提供预期的结果,但经过一些测试后它可以正常工作,请发表评论。
基本上我从 Firestore get 查询的快照中计算结果以查看 fbEventId 是否已经存在,如果不存在我写新的 FB 事件,如果它已经存在,我返回。
static func getFBEvents() {
let graphRequest : GraphRequest = GraphRequest(graphPath: "/me", parameters: ["fields":"id, events"], httpMethod: .get)
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print("Error took place: \(String(describing: error))")
}
else {
print("Print entire fetched result for events: \(String(describing: result))")
if let dictionary = result as? [String: Any] {
if let dictionary1 = dictionary["events"] as? [String: Any]{
if let dataList = dictionary1["data"] as? [[String: Any]] {
dataList.forEach { dictionary in
let eventDescription = dictionary["description"] as? String
let fbEventId = dictionary["id"] as? String
let eventName = dictionary["name"] as? String
let eventStart = dictionary["start_time"] as? String
if let nestedDictionary = dictionary["place"] as? [String: Any] {
let eventLocation = nestedDictionary["name"] as? String
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("events").whereField("fbEventId", isEqualTo: fbEventId!).getDocuments() { (querySnapshot, err) in
let size = querySnapshot?.count
if let err = err {
print("Error \(err)")
return
}
//If size of snapshot is equal to 0, FB event doesn't exist in user event collection so write fb event
else {
if size! == 0 {
print("event does not already exists, writing event to Firestore")
let newDocument = Firestore.firestore().collection("events").document()
//Create a dictionary for the event
let eventData = ["eventDescription":eventDescription, "eventStart":eventStart,"fbEventId": fbEventId, "eventCreated": Timestamp(date: Date()), "eventId": newDocument.documentID, "eventName": eventName, "eventSource": "FB", "eventLocation": eventLocation] as [String : Any]
//Create the profile for the event
newDocument.setData(eventData) { (error) in
if error != nil {
print("There was an error")
}
else {
}
}//close Firestore setData
}
else {
print("event already exists")
//Get a Firebase reference
return
}
}}}}}}}}})}}
我正在尝试检查 FB 事件是否已作为文档存在于我的 Firestore 集合中,如果不存在,则将新的 FB 事件作为新文档写入。我的问题是,当将解析的图形请求 'results' 字典与我集合中的 fbEventIds 进行比较时,逻辑设置不正确并创建重复而不是避免它们。
逻辑上我的功能是如何设置的:
func getFbEvents {
fbgraphrequest {
parse graphrequest results into an Event object {
get Firestore snapshot of 'events' collection {
//Compare graph request event id to event ids stored in firestore
if graphrequesteventId == FirestoresnapshoteventsFbId {
return
}
else {
setdata of new fb event in firestore events collection
}}}}}
实际代码
我已经尝试在解析字典之后和基于其他 SO 线程检索快照之前添加 DispatchGroup 和 DispatchQueue enter 和 leave 命令,但它仍然不适用于我的代码。
static func getFBEvents() {
let graphRequest : GraphRequest = GraphRequest(graphPath: "/me", parameters: ["fields":"id, events"], httpMethod: .get)
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
}
else {
if let dictionary = result as? [String: Any] {
if let dictionary1 = dictionary["events"] as? [String: Any]{
if let dataList = dictionary1["data"] as? [[String: Any]] {
dataList.forEach { dictionary in
let eventDescription = dictionary["description"] as? String
let fbEventId = dictionary["id"] as? String
let eventName = dictionary["name"] as? String
let eventStart = dictionary["start_time"] as? String
if let nestedDictionary = dictionary["place"] as? [String: Any] {
let eventLocation = nestedDictionary["name"] as? String
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("events").getDocuments() { (querySnapshot, err) in
if let err = err {
return
}
else {
for doc in querySnapshot!.documents {
let e = Event(snapshot: doc)
print("fb eventId: \(e?.fbEventId) & \(fbEventId)")
if e!.fbEventId != fbEventId {
print("event does not already exists, writing event to Firestore")
let newDocument = Firestore.firestore().collection("events").document()
//Create a dictionary for the event
let eventData = ["eventDescription":eventDescription, "eventStart":eventStart,"fbEventId": fbEventId, "eventCreated": Timestamp(date: Date()), "eventId": newDocument.documentID, "eventName": eventName, "eventSource": "FB", "eventLocation": eventLocation] as [String : Any]
//Create the profile for the event
newDocument.setData(eventData) { (error) in
if error != nil {
}
else {
}
}//close Firestore setData
}
else {
return
}
}
}
}//close retrieve events
}//close nested Dictionfary for place
}//close datalist for each
}//close datalist
}//close dictionary1
}//close dictionary
}//close else
}//close graph request start
)}//close getFBEvents
}
经过更多的挖掘,我想我得到了我需要的东西。如果您认为这不会提供预期的结果,但经过一些测试后它可以正常工作,请发表评论。
基本上我从 Firestore get 查询的快照中计算结果以查看 fbEventId 是否已经存在,如果不存在我写新的 FB 事件,如果它已经存在,我返回。
static func getFBEvents() {
let graphRequest : GraphRequest = GraphRequest(graphPath: "/me", parameters: ["fields":"id, events"], httpMethod: .get)
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if error != nil {
print("Error took place: \(String(describing: error))")
}
else {
print("Print entire fetched result for events: \(String(describing: result))")
if let dictionary = result as? [String: Any] {
if let dictionary1 = dictionary["events"] as? [String: Any]{
if let dataList = dictionary1["data"] as? [[String: Any]] {
dataList.forEach { dictionary in
let eventDescription = dictionary["description"] as? String
let fbEventId = dictionary["id"] as? String
let eventName = dictionary["name"] as? String
let eventStart = dictionary["start_time"] as? String
if let nestedDictionary = dictionary["place"] as? [String: Any] {
let eventLocation = nestedDictionary["name"] as? String
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("events").whereField("fbEventId", isEqualTo: fbEventId!).getDocuments() { (querySnapshot, err) in
let size = querySnapshot?.count
if let err = err {
print("Error \(err)")
return
}
//If size of snapshot is equal to 0, FB event doesn't exist in user event collection so write fb event
else {
if size! == 0 {
print("event does not already exists, writing event to Firestore")
let newDocument = Firestore.firestore().collection("events").document()
//Create a dictionary for the event
let eventData = ["eventDescription":eventDescription, "eventStart":eventStart,"fbEventId": fbEventId, "eventCreated": Timestamp(date: Date()), "eventId": newDocument.documentID, "eventName": eventName, "eventSource": "FB", "eventLocation": eventLocation] as [String : Any]
//Create the profile for the event
newDocument.setData(eventData) { (error) in
if error != nil {
print("There was an error")
}
else {
}
}//close Firestore setData
}
else {
print("event already exists")
//Get a Firebase reference
return
}
}}}}}}}}})}}