添加 .whereField 时无法从 Firestore 检索文档

问题描述 投票:0回答:1

我已将 Gemini ChatBot 扩展添加到 Firebase 项目中。

示例:https://medium.com/google-cloud/build-a-chatbot-on-ios-with-the-firebase-gemini-api-extension-in-swift-swiftui-a-step-by-步骤-64657205ca80

我已通过发送消息功能将

profile!.uid
添加到文档中,这样我只能检索用户
ChatDocuments

func sendMessage(_ message: String) {
    guard let profileId = profile?.uid else {
        print("Profile ID not found")
        return
    }
    
    let data: [String: Any] = [
        "prompt": message,
        "userID": profileId,
    ]
    
    db.collection(collectionPath).addDocument(data: data) { error in
        if let error = error {
            print("Error adding document: \(error)")
        } else {
            print("Document added for userID: \(profileId)")
        }
    }
}

此时,应用程序已成功将文档添加到 FireStore,并且扩展程序添加了响应。

响应是使用以下函数显示在 UI 中。

func fetchMessages() {
    print("Fetch messages called for userID: \(profile!.uid)")
    db.collection(collectionPath)
        .whereField("userID", isEqualTo: profile!.uid)
        .order(by: "createTime", descending: false)
        .addSnapshotListener { [weak self] querySnapshot, error in
            guard let self else { return }
            guard let documents = querySnapshot?.documents else {
                print("No documents found")
                return
            }
            
            self.messages = documents.compactMap { queryDocumentSnapshot -> [ChatMessage]? in
                do {
                    let document = try queryDocumentSnapshot.data(as: ChatDocument.self)
                    
                    let prompt = ChatMessage(text: document.prompt, isUser: true, state: .COMPLETED)
                    let response = ChatMessage(text: document.response ?? "", isUser: false, state: document.status.chatState)
                    print("RESPONSE FROM DOCUMENTS")
                    print("fetched \(response)")
                    
                    return [prompt, response]
                } catch {
                    print(error.localizedDescription)
                    return nil
                }
            }.flatMap { $0 }
        }
}

但是,当添加以下行时,不会获取文档。

.whereField("userID", isEqualTo: profile!.uid)

聊天文档

struct ChatDocument: Codable {
    let createTime: Timestamp
    let prompt: String
    let response: String?
    let status: Status
    let userID: String

    struct Status: Codable {
        let startTime: Timestamp?
        let completeTime: Timestamp?
        let updateTime: Timestamp
        let state: String
        let error: String?
        
        var chatState: ChatState {
            return ChatState(rawValue: state) ?? .PROCESSING
        }
    }
}

struct ChatMessage: Hashable {
    
    @ServerTimestamp var createdTime: Timestamp?
    @DocumentID var uid: String?
    
    private(set) var id: UUID = .init()
    var text: String?
    var isUser: Bool
    var state: ChatState = .PROCESSING
    
    
    var message: String {
        switch state {
        case .COMPLETED:
            return text ?? ""
        case .ERROR:
            return "Something went wrong. Please try again."
        case .PROCESSING:
            return "..."
        }
    }
    
}

enum ChatState: String, Codable {
    case COMPLETED
    case ERROR
    case PROCESSING
}

FireStore:

enter image description here

有趣的是,以下内容删除了

profile.uid
的所有文档并使用相同的
.whereField("userID", isEqualTo: profile!.uid)

func removeAllMessages() async {
    
    do {
        let querySnapshot = try await db.collection(collectionPath)
            .whereField("userID", isEqualTo: profile!.uid)
            .getDocuments()
        
        for document in querySnapshot.documents {
            do {
                try await db.collection(collectionPath).document(document.documentID).delete()
                self.messages.removeAll()
                print("Document with ID \(document.documentID) successfully removed!")
            } catch {
                print("Error removing document with ID \(document.documentID): \(error)")
            }
        }
    } catch {
        print("Error querying documents for profileId \(profile!.uid): \(error)")
    }
}
ios swift firebase google-cloud-firestore
1个回答
0
投票

您很可能缺少此组合所需的复合索引:

.whereField("userID", isEqualTo: profile!.uid)
.order(by: "createTime", descending: false)

最简单的解决方案是捕获并记录代码引发的任何错误,因为这将包含 Firestore 控制台用于创建链接的 URL - 所有字段均已填写。

要了解有关 Firestore 索引逻辑的更多信息,请阅读有关 索引类型复合索引创建所需索引的文档。

© www.soinside.com 2019 - 2024. All rights reserved.