在Firebase中保存数组 [英] Saving Array in Firebase

查看:169
本文介绍了在Firebase中保存数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

  func signUpUserWithBasicInfo(emailId:String!,密码:String !,用户名:String !,年龄:字符串,性别: String !, backpackerType:String,info:[String:AnyObject],completionBlock:(() - > Void)){

print(fir signup did recieve)
FIRAuth。 auth()?。createUserWithEmail(emailId,password:password,completion:{
user,
$ b $ if if error!= nil {
print(error while backend email注册握手:\(错误))
print()
self.delegate.firShowAlert(错误注册你,乱年龄:请检查您的网络或此电子邮件已存在!)

}其他{
print(上传数据库)
self.profilePictureUploading(info,completionBlock:{

FIRControllerClass.ref.child(UserProfile)。child(user!.uid).setValue([
username:username,
email:emailId,
age:年龄,
gender:性别,
password:密码,
typeOfBackpacker:backpackerType
))

completionBlock()

))
}
})
}

func profilePictureUploading(infoOnThePicture:[String:AnyObject] ,completionBlock:(() - > Void)){

如果让referenceUrl = infoOnThePicture [UIImagePickerControllerReferenceURL] {
print(referenceUrl)
let assets = PHAsset.fetch AssetsWithALAssetURLs([ReferenceUrl as! NSURL],options:nil)
print(assets)
let asset = assets.firstObject
print(asset)
asset?.requestContentEditingInputWithOptions(nil,completionHandler:{(ContentEditingInput, (imageFile)\(imageFile))

let filePath = FIRAuth.auth()在

中使用imageFile = ContentEditingInput?.fullSizeImageURL
print !.currentUser!.uid +/ \(Int(NSDate.timeIntervalSinceReferenceDate()* 1000))/ \(imageFile!.lastPathComponent!)
print(filePath:\(filePath))

$ {







$如果错误!=无{

打印(上传图像时出错:\(错误))
self.delegate.firShowAlert(Error Uploading Your (metadata)in:\(metadata!),请检查您的网络!)
}

else {

print )
print(metadata?.downloadURL())
print(图片已上传)
print(download url:\(metadata?.downloadURL()))

self.uploadSuccess(metadata !, storagePath:filePath)

completionBlock()

}

})
$)

} else {
print(No reference URL found!)
}
}


如何在我的后端创建一个用作数组的子对象,以及如何检索该数组?



我的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 @ gmai l.com,
gender:F,
password:123454321,
typeOfBackpacker:Group,
username Cathy


}

我也需要在我的数据库(数组)中添加 no的朋友的数组。我使用for循环的唯一原因是我可以向用户显示每个用户的详细信息从他/她自己)使用我在我的数据库中创建的userId数组,这实际上是我的每个相应的用户数据库的父节点。



这就是我在我的数据库中追加 UserId 的方法:

  func retrieveUserIdsArray(completionBlock:((attachedArr:NSMutableArray) - > Void)){

var additionalArray:NSMutableArray = []

FIRControllerClass.ref.child(UserId)。如果让userIdDetails = snapshot.value为?NSMutableArray {$ b())中的observeEventType(FIRDataEventType.Value,withBlock:{(snapshot)in


$ userIdDetails.addObject((FIRAuth.auth()?。currentUser?.uid)!)
attachedArray = userIdDetails

completionBlock(appendArr:attachedArray)






$ b

在此调用函数:
$ b $ pre $ func signUpUserWithBasicInfo(emailId:String!,密码:String !,用户名:String !,年龄:字符串,性别: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(后台电子邮件注册时遇到错误握手:\(错误))

print()

self.delegate.firShowAlert(注册错误,信息:请检查您的网络或此电子邮件已经存在!)

} else {

print(uploading database)

self.profilePictureUploading(info,completionBlock:{

FIRControllerClass.ref.child(UserProfile)。child(user !.uid).setValue([
username:username,
email:emailId,
age:age,
gender:gender,
密码:密码,
typeOfBackpacker:backp ackerType
])


var a = 0

self.retrieveUserIdsArray({(attachedArr)in

a + = 1
$ b $ print(附加数组是:\(attachedArr))

如果a == 1 {

FIRControllerClass.ref。 child(UserId)。setValue(attachedArr)

} else {

completionBlock()




$






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

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

解决方案

因为单个元素不能直接访问或改性。你可以读整个数组或者写整个数组。



我建议改变Structure来更好地匹配你想要的数据, b
$ b $ p $ UserProfile:{
D8QmnOSH6vRYiMujKNXngzhdn992:{
age:12,
电子邮件: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))//等于friend_of / aCgAFAGDIgWRSUu9a2aMo9HtnnD3
var userIdArray = [String]()
userProfileRef.queryOrderedByChild(path)
.queryEqualToValue(true)
.observeSingleEventOfType(.Value,withBlock:{snapshot in
for snapshot.children中的孩子{
let userId = child.key as String
userIdArray.append(userId)
}
//循环完成,现在我们有一个userIds数组,它们是好友
})

代码返回每个在我的用户(myUid)上的用户。

我还添加了一个friend count节点,那个用户数量的朋友。当添加好友时,增加值,当删除减少。这是一个快速的

  myUid.child(friend_count)。setValue(updated_count)

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





$ p
$ b $ p $ c> let myRef = self.myRootRef.child(array_node)
myRef.observeSingleEventOfType(.Value,withBlock:{snapshot in

let a = snapshot.value as!NSArray
print(a)// a a NSArray

let b =(a as Array).filter {$ 0 is String}

print(b)// b是一个Swift数组

print(b [1])$ ​​b $ b})


I am using Firebase 3.0 as my backend, and I need to save my every user.uid in a separate child which needs to be an NSArray, and then retrieve that array using a for loop!

This is how I am saving my data: I have created a separate class for the FIRController which is handling all the storing and retrieving of database and storage.

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!")
    }
}

How would I create a child in my backend which would serve as array, and how can I retrieve that array?

My firebase JSON STRUCTURE : -

{
  "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
}

i also need to add an array of no of friends in my database(array).The only reason i am using for loop is so that i can display every user's details to my user(apart from him/her self) using the userId array that i have created in my database, which are actually the parent node to my every respective user database.

This is how i am appending UserId in my database :-

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)

        }
    })
} 

which is called in this function :-

    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()

                    }
                })
            })
        }
    })
}

The reason why i have used a variable is to tackle the infinite loop which it was causing(i know its just a hack, for now ..)

Open to any better way to tackle this!..

解决方案

Array's can be challenging in Firebase as the individual elements cannot be accessed directly or modified. You either read the whole array or write the whole array.

I would suggest changing the Structure to better match the data you want and avoid array's entirely:

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

then a simple deep query will return everything you need (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
})

The code returns every user who is a friend on mine (myUid)

I've also added a 'friend count' node that simply keeps a count of that users number of friends. When a friend is added, increment the value, when removed decrement. It's a quick

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

This code also avoids loops, callbacks and additional completion blocks because it rely's on Firebase to get the data, and let us know when it's done.

If you really, really want to read an array node (not recommended)

    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] )
    })

这篇关于在Firebase中保存数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆