使用 objectId 获取多个 ParseObjects
Fetch several ParseObjects with objectId
我正在使用 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 文档中读到,可以根据对象的 objectId 同时获取多个对象,因此我的想法是创建一个虚拟 Userdata 对象数组,其中包含要获取的 objectId。但是,这不起作用。
如代码块中所示,我能够缩小错误范围,并且在执行查询时,fetchedData
以 ParseError
的形式返回:
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
- Swift 5
- 解析Swift 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?
}
您确定 UserData 的对象 ID 与用户 ID 相同吗?虽然您可能在 class 中有用户 ID,但它可能不是 objectId,而是其他一些存储字段。
正在做
let query = PFQuery(className:"UserData")
query.whereKey("userId", containedIn:userdataIdArray)
query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
// do stuff
}
可能会有帮助。
您应该在 Parse Dashboard 中检查您的 Class Level Permissions (CLP's) and here,如果您使用的是默认配置,则无法查询 _User
class,除非您使 CLP 的 [=19] =] 或授权。此外,您可以通过使用查询和查找对象而不是构建用户对象和获取您正在做的方式来缩减代码:
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
我正在使用 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 文档中读到,可以根据对象的 objectId 同时获取多个对象,因此我的想法是创建一个虚拟 Userdata 对象数组,其中包含要获取的 objectId。但是,这不起作用。
如代码块中所示,我能够缩小错误范围,并且在执行查询时,fetchedData
以 ParseError
的形式返回:
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
- Swift 5
- 解析Swift 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?
}
您确定 UserData 的对象 ID 与用户 ID 相同吗?虽然您可能在 class 中有用户 ID,但它可能不是 objectId,而是其他一些存储字段。
正在做
let query = PFQuery(className:"UserData")
query.whereKey("userId", containedIn:userdataIdArray)
query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
// do stuff
}
可能会有帮助。
您应该在 Parse Dashboard 中检查您的 Class Level Permissions (CLP's) and here,如果您使用的是默认配置,则无法查询 _User
class,除非您使 CLP 的 [=19] =] 或授权。此外,您可以通过使用查询和查找对象而不是构建用户对象和获取您正在做的方式来缩减代码:
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