在Firebase中保存数组

我使用的是Firebase 3.0作为后端,我需要将每个user.uid保存在一个需要成为NSArray的独立子user.uid中,然后使用for循环检索该数组!

这是我如何保存我的数据:我已经为FIRController创build了一个单独的类,它正在处理数据库和存储的所有存储和检索。

 func signUpUserWithBasicInfo(emailId : String! , password : String!, username : String!, age : String, gender : String!, backpackerType : String, info : [String : AnyObject], completionBlock : (() -> Void)){ print("fir signup did recieve") FIRAuth.auth()?.createUserWithEmail(emailId, password: password, completion: { user,error in if error != nil{ print("error encountered while backend email signup Handshake : \(error)") print("") self.delegate.firShowAlert("Error signing you up", Message: "Please check your network or this email already exist!") }else{ print("uploading database") self.profilePictureUploading(info, completionBlock: { FIRControllerClass.ref.child("UserProfile").child(user!.uid).setValue([ "username" : username, "email" : emailId, "age" : age, "gender" : gender, "password" : password, "typeOfBackpacker" : backpackerType ]) completionBlock() }) } }) } func profilePictureUploading(infoOnThePicture : [String : AnyObject],completionBlock : (()->Void)) { if let referenceUrl = infoOnThePicture[UIImagePickerControllerReferenceURL] { print(referenceUrl) let assets = PHAsset.fetchAssetsWithALAssetURLs([referenceUrl as! NSURL], options: nil) print(assets) let asset = assets.firstObject print(asset) asset?.requestContentEditingInputWithOptions(nil, completionHandler: { (ContentEditingInput, infoOfThePicture) in let imageFile = ContentEditingInput?.fullSizeImageURL print("imagefile : \(imageFile)") let filePath = FIRAuth.auth()!.currentUser!.uid + "/\(Int(NSDate.timeIntervalSinceReferenceDate() * 1000))/\(imageFile!.lastPathComponent!)" print("filePath : \(filePath)") FIRControllerClass.storageRef.child("ProfilePictures").child(filePath).putFile(imageFile!, metadata: nil, completion: { (metadata, error) in if error != nil{ print("error in uploading image : \(error)") self.delegate.firShowAlert("Error Uploading Your Profile Pic", Message: "Please check your network!") } else{ print("metadata in : \(metadata!)") print(metadata?.downloadURL()) print("The pic has been uploaded") print("download url : \(metadata?.downloadURL())") self.uploadSuccess(metadata!, storagePath: filePath) completionBlock() } }) }) } else { print("No reference URL found!") } } 

我将如何创build一个后端将作为数组,我怎样才能检索该数组?

我的firebase JSON结构: –

 { "UserId" : [ 1, "Sq5EDvVOsQWkLylEx3GrBdEsIN92", "xC4jCJmobUcqghq8C3SI1XT0UPk1", "D8QmnOSH6vRYiMujKNXngzhdn992", "riHjon6wknOmALwf0Z0Ri5aOMA82", "fKqlb88MKsYCE43xy7D51qH6jqH3", "aCgAFAGDIgWRSUu9a2aMo9HtnnD3", "iicKACGo8RaeTSEggKPB0sU2Bme2", "qJ2c8AcEYzVkJKLl13N92tyKnbz2" ], "UserProfile" : { "D8QmnOSH6vRYiMujKNXngzhdn992" : { "age" : "12", "email" : "dummy1@gmail.com", "gender" : "f", "password" : "123454321", "typeOfBackpacker" : "dummy", "username" : "duummyy1" }, "Sq5EDvVOsQWkLylEx3GrBdEsIN92" : { "age" : "121", "email" : "ghfgh@gnag.com", "gender" : "gjhg", "password" : "123454321", "typeOfBackpacker" : "chef", "username" : "hgfgh" }, "aCgAFAGDIgWRSUu9a2aMo9HtnnD3" : { "age" : "24", "email" : "cathydurrant@gmail.com", "gender" : "F", "password" : "123454321", "typeOfBackpacker" : "Group", "username" : "Cathy" }, etc } 

我还需要在我的数据库(数组)中添加一个no of friends数组。我使用循环的唯一原因是,我可以显示每个用户的详细信息给我的用户(除了他/她自己)使用userId数组我已经创build了我的数据库,这实际上是我的每个用户数据库的父节点。

这是我如何追加UserId在我的数据库中: –

 func retrieveUserIdsArray(completionBlock : ((appendedArr : NSMutableArray) -> Void)){ var appendedArray : NSMutableArray = [] FIRControllerClass.ref.child("UserId").observeEventType(FIRDataEventType.Value, withBlock: {(snapshot) in if let userIdDetails = snapshot.value as? NSMutableArray{ userIdDetails.addObject((FIRAuth.auth()?.currentUser?.uid)!) appendedArray = userIdDetails completionBlock(appendedArr: appendedArray) } }) } 

这在这个函数中被调用:

  func signUpUserWithBasicInfo(emailId : String! , password : String!, username : String!, age : String, gender : String!, backpackerType : String, info : [String : AnyObject], completionBlock : (() -> Void)){ print("fir signup did recieve") FIRAuth.auth()?.createUserWithEmail(emailId, password: password, completion: { user,error in if error != nil{ print("error encountered while backend email signup Handshake : \(error)") print("") self.delegate.firShowAlert("Error signing you up", Message: "Please check your network or this email already exist!") }else{ print("uploading database") self.profilePictureUploading(info, completionBlock: { FIRControllerClass.ref.child("UserProfile").child(user!.uid).setValue([ "username" : username, "email" : emailId, "age" : age, "gender" : gender, "password" : password, "typeOfBackpacker" : backpackerType ]) var a = 0 self.retrieveUserIdsArray({ (appendedArr) in a += 1 print("The appended array is : \(appendedArr)") if a == 1{ FIRControllerClass.ref.child("UserId").setValue(appendedArr) }else{ completionBlock() } }) }) } }) } 

我之所以使用avariables是为了解决它造成的无限循环(我知道它只是一个黑客,现在..)

打开任何更好的方式来解决这个问题!

arrays在Firebase中可能具有挑战性,因为单个元素无法直接访问或修改。 你要么读整个数组,要么写整个数组。

我会build议改变结构,以更好地匹配你想要的数据,并避免数组的完全:

 "UserProfile" : { "D8QmnOSH6vRYiMujKNXngzhdn992" : { "age" : "12", "email" : "dummy1@gmail.com", "gender" : "f", "password" : "123454321", "typeOfBackpacker" : "dummy", "username" : "duummyy1" "friend_count": 10 "friend_of" "aCgAFAGDIgWRSUu9a2aMo9HtnnD3": true }, 

那么一个简单的深层查询将会返回您需要的一切(Firebase v2)

 let myUid = "aCgAFAGDIgWRSUu9a2aMo9HtnnD3" let path = ("friend_of/\(myUid)") // equals friend_of/aCgAFAGDIgWRSUu9a2aMo9HtnnD3 var userIdArray = [String]() userProfileRef.queryOrderedByChild(path) .queryEqualToValue(true) .observeSingleEventOfType(.Value, withBlock: { snapshot in for child in snapshot.children { let userId = child.key as String userIdArray.append(userId) } //loop is done, now we have an array of userIds that are friends }) 

该代码返回每个用户谁是我的朋友(myUid)

我还添加了一个“朋友计数”节点,只是保持该用户的朋友数量的计数。 当添加好友时,增加值,当删除减less。 这很快

 myUid.child("friend_count").setValue(updated_count) 

此代码还避免了循环,callback和附加完成块,因为它依靠Firebase获取数据,并在完成时告诉我们。

如果真的,真的想读一个数组节点(不推荐)

  let myRef = self.myRootRef.child("array_node") myRef.observeSingleEventOfType(.Value, withBlock: { snapshot in let a = snapshot.value as! NSArray print(a) //a an NSArray let b = (a as Array).filter {$0 is String} print(b) //b is a Swift Array print( b[1] ) })