【问题标题】:Fetch several ParseObjects with objectId使用 objectId 获取多个 ParseObjects
【发布时间】:2022-01-06 19:19:11
【问题描述】:

我正在使用 ParseSwift 更新 iOS 应用程序。一般来说,应用程序的每个 ParseUser 都有几个需要查询或获取的关联 Userdata ParseObjects。

当前的实现使用单独的查询一个接一个地查找每个单独的 Userdata 对象。这可行,但显然不是最佳的。

我已经修改的是每个 ParseUser 现在都保存了一个与用户相关的 Userdata ParseObjects 的 objectId 数组。

我现在想要实现的是在 ParseUser 的 userdataIds 字段中查询与这些保存的 objectId 对应的所有 Userdata 对象。

这是我的代码:

func asyncAllUserdataFromServer() {
    let userdataIdArray = User.current!.userdataIds

    var objectsToBeFetched = [Userdata]()

    userdataIdArray?.forEach({ objectId in
        let stringObjectId = objectId as String
            
        // create a dummy Userdata ParseObject with stringObjectId
        let object = Userdata(objectId: stringObjectId)
            
        // add that object to array of Userdata objects that need to be fetched
        objectsToBeFetched.append(object)
    })
        
    // fetch all objects in one server request
    objectsToBeFetched.fetchAll { result in
        switch result {
        case .success(let fetchedData):
            
        // --- at this point, fetchedData is a ParseError ---
        // --- here I want to loop over all fetched Userdata objects ---

        case .failure(let error):
            ...
        }
    }
}

我在 ParseSwift 文档中读到,可以根据它们的 objectIds 同时获取多个对象,因此我的想法是创建一个包含要获取的 objectIds 的虚拟 Userdata 对象数组。但是,这不起作用。

如代码块所示,我能够缩小错误范围,并且在执行查询时,fetchedDataParseError 的形式返回:

Error fetching individual object: ParseError code=101 error=objectId "y55wmfYTtT" was not found in className "Userdata"

具有该 objectId 的 Userdata 对象是保存在 User.current.userdataIds 数组中的第一个(也是唯一一个)objectId。这个对象确实存在于我的服务器上,我肯定知道。

任何想法为什么它无法获取?

一般信息:

  • Xcode 13.2.1
  • 斯威夫特 5
  • ParseSwift 2.5.0
  • Back4App 后端

编辑:

用户实现:

struct User: ParseUser {

    //: These are required by `ParseObject`.
    var objectId: String?
    var createdAt: Date?
    var updatedAt: Date?
    var ACL: ParseACL?

    //: These are required by `ParseUser`.
    var username: String?
    var email: String?
    var emailVerified: Bool?
    var password: String?
    var authData: [String: [String: String]?]?

    //: Custom keys.
    var userdataIds: [String]?  // --> array of Userdata objectId's

}

用户数据实现:

struct Userdata: ParseObject, ParseObjectMutable {
    
    var objectId: String?
    var createdAt: Date?
    var updatedAt: Date?
    var ACL: ParseACL?
    
    var firstname: String?
    var lastSeen: Int64?
    var isLoggedIn: Bool?
    var profilepicture: ParseFile?
    
}

【问题讨论】:

    标签: swift parse-platform parse-server


    【解决方案1】:

    您应该在 Parse Dashboard 中检查您的 Class Level Permissions (CLP's)here,如果您使用默认配置,则除非您将 CLP 公开或授权,否则您无法查询 _User 类。此外,您可能可以通过使用查询和查找对象来缩小代码,而不是构建用户对象并获取您正在执行的方式:

    let userdataIdArray = User.current!.userdataIds
    let query = Userdata.query(containedIn(key: "objectId", array: userdataIdArray))
    
    //Completion block
    query.find { result in
      switch result {
      case .success(let usersFound):
        ...
      case .failure(let error):
        ...
      }
    }
    
    // Async/await
    do {
      let usersFound = try await query.find()
      ...
    } catch {
      ...
    }
    

    您还应该查看您的服务器设置以确保此选项正在执行您希望它执行的操作:https://github.com/parse-community/parse-server/blob/4c29d4d23b67e4abaf25803fe71cae47ce1b5957/src/Options/docs.js#L31

    【讨论】:

    • 嘿,Corey,我只是用你描述的查询而不是获取它来尝试它,现在它就像一个魅力,谢谢!
    • 只有一个关于性能的后续问题:我想使用 fetch,因为我认为 fetch 总是比查询快。这是正确的还是两种方式都具有相似的性能? (至少在这个例子中)
    • 由于您使用的是fetchAll,因此无论如何它都使用相同的查找查询,因此它们都具有相同的性能:github.com/parse-community/Parse-Swift/blob/…。你可以使用任何一个。性能将取决于您的数据库(Postgres 或 Mongo)。 objectId 有一个默认索引,所以你应该没问题
    【解决方案2】:

    您确定 UserData 的对象 ID 与用户 ID 相同吗?虽然您可能在类中有用户 ID,但它可能不是 objectId,而是其他一些存储字段。

    在做

    let query = PFQuery(className:"UserData")
    query.whereKey("userId", containedIn:userdataIdArray)
    query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
    // do stuff
    }
    

    可能会有所帮助。

    【讨论】:

    • 您好帕特里克,感谢您的意见。我很肯定 ParseUser 的 userdataId 数组对应于 Userdata ParseObjects 的实际 objectId。我上面的代码示例尝试获取一个在注册时创建的 Userdata 对象:注册 ParseUser 后,创建了一个 Userdata 对象,保存到服务器,然后将这个新创建的 Userdata 对象的 objectId 保存到 ParseUser 的 userdataId 数组。
    • 我假设您的代码适用于 Parse-SDK。由于我使用的是 ParseSwift SDK,我不确定如何翻译您的代码示例。我有使用 Android SDK 的经验,您的代码看起来就像我在应用程序的 Android 版本中实现此行为的方式,但对于 iOS 版本,我决定追求完整的 Swift 实现。
    • 你查看过这个链接了吗:parseplatform.org/Parse-Swift/api/Protocols/…我没有时间再写完整的语法了。此外,为 User 和 Userdata 发布您的类结构的图片可能会有所帮助
    • 我将使用我的 ParseUser 和 Userdata 实现来更新我的问题。
    • 所以,很抱歉这个愚蠢的问题,但只是。确认。您已经仔细检查过您有一个具有该 ID 的用户数据
    猜你喜欢
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多