EQOxx123 EQOxx123 - 4 months ago 28x
iOS Question

Cycling through value event types and making value UIButton's titleLabel with Firebase in swift

Inside of my app I have seem to have ran into an error. Not a runtime error or a bug, but not being able to figure out how to do something or where to go with it. In one part of my app, users can post data to my firebase using a firebase reference in swift. In another part, where I am getting stuck, is how to not only read that data, but then organize that. I have a list of ten UIButtons on a view controller and I am trying to have it so that every time the value is changed using Firebase's method

.observeEventType(.Value, withBlock: { snapshot in })
to catch the
and then downcast it as a String using
as! String
and then make that, the most recent data, my first UIButton's title and my second UIButton's title is the old first Unbutton's title etc. until the ninth UIButton's title is the tenth and the tenth is ignored. Basically a cycle of the UIButton's title based on the ten most recent posts to firebase. Any help would be great and i hope this helps other people! Thanks! Below is an attempt at the code:

override func viewDidLoad() {


// firebase reference is defined

// UIButtons deck1 - deck10 are defined

refName.observeEventType(.Value, withBlock: { snapshot in

// however all that happens is that only the first UIButton's title is updated with the new data ( snapshot.value as! String )

self.deck10.titleLabel!.text! = self.deck9.titleLabel!.text! // backwards attempt so values do not overlap

self.deck9.titleLabel!.text! = self.deck8.titleLabel!.text!

self.deck8.titleLabel!.text! = self.deck7.titleLabel!.text!

self.deck7.titleLabel!.text! = self.deck6.titleLabel!.text!

self.deck6.titleLabel!.text! = self.deck5.titleLabel!.text!

self.deck5.titleLabel!.text! = self.deck4.titleLabel!.text!

self.deck4.titleLabel!.text! = self.deck3.titleLabel!.text!

self.deck3.titleLabel!.text! = self.deck2.titleLabel!.text!

self.deck2.titleLabel!.text! = self.deck1.titleLabel!.text!

self.deck1.titleLabel!.text! = snapshot.value as! String


By the way, the users are only posting Strings to firebase but just to be safe it might be best to use
snapshot.value as? String
to check if it is a string or otherwise return nil.

Jay Jay

I think this is what you are after...

First thing you want to do is load the last 10 (most current) values from Firebase into an array. That array will be used to populate and maintain your button titles. You also want to keep a reference to the buttons in an array as well. Some of this is off the top of my head so don't copy paste!

var titleArray = [String]()
var buttonArray = [NSButton]()  //populate this with 10 button references

titlesRef.queryLimitedToLast(10).observeSingleEventOfType(.Value, withBlock : {
     snapshot in

     for child in snapshot.children {
          let title = child.value["title"] as! String

     //data will be ascending, newest at the bottom, reverse that
     self.titleArray = self.titleArray.reverse()

     for index in 0...9
        self.buttonArray[index].title = self.titleArray[index] as! String

Then add an observer to your node which will notify you of the most current title added.

titlesRef.queryLimitedToLast(1).observeEventType(.ChildAdded, withBlock : {
     snapshot in

     let title = snapshot.value["title"] as! String

     //always add the most current at the 'top' of the array
     titleArray(title, atIndex: 0)

     //remove the oldest index

     //iterate over the buttonsArray and update their titles

The tricky bit is that Firebase .Value will be in ascending order, meaning the oldest title will be the first read in and the newest will be the last. We use .reverse() to reverse the ordering of the titlesArray so the newest title will be at the top.

From then on we are observing the newest title added to Firebase, reading it in and inserting it at the top of the array, then refreshing the button titles, popping off the last (oldest).

Another option is: instead of observing the last title added and inserting it, you could


which, when the last 10 change will read them all in. You could then iterate over that (reverse!) and update your buttons. That actually might be less code but it's reading in more data.

edit: This may actually be the better option. Here's the code

titlesRef.queryLimitedToLast(10).observeEventType(.Value, withBlock : { snapshot in

    for child in snapshot.children {
        let title = child.value["title"] as! String

    titleArray = titleArray.reverse()

    for index in 0...9 {
      let title = titleArray[index]
      self.buttonArray[index].title = titleArray[index]