簡體   English   中英

Firebase快速查詢的查詢性能

[英]firebase swift queries in queries performance

我是Firebase的新手,也是Swift的新手。

我的firebase設置如下。 我有用戶,關注者和被阻止的用戶。 我照顧UITableViewCell類中的關注者。 我想知道,在進一步介紹之前,如何將查詢中的觀察者置於查詢中,從而對性能產生影響? (希望這些是正確的術語)。 下面是正確的解決方法嗎(最有效的方法)。 它有效,但似乎也有些斷斷續續。 我感謝任何反饋。

{
  "BlockedByUsers" : {
    "ba1eb554-9a81-4a74-bfd9-484a32eee13d" : {
    "97fee08f-19b2-4eb5-9eab-4b1985c22595" : true
    }
  },
 "Dates" : {
    "1457635040" : {
    "97fee08f-19b2-4eb5-9eab-4b1985c22595" : true
    },
  },
 "Locations" : {
    "97fee08f-19b2-4eb5-9eab-4b1985c22595" : {
    ".priority" : "u14dkwm41h",
    "g" : "u14dkwm41h",
    "l" : [ 51.05521018175982, 3.720297470654139 ]
    },
  },
 "Users" : {
   "97fee08f-19b2-4eb5-9eab-4b1985c22595" : {
   "blockedUsers" : {
      "ba1eb554-9a81-4a74-bfd9-484a32eee13d" : true
    },
   "following" : {
     "51879163-8b35-452b-9872-a8cb4c84a6ce" : true,
    },
   "fullname" : "",
   "dates" : 1457635040,
   "location" : "",
  },
 }
} 

我擔心的帶有多個查詢的Swift代碼:

var usersRef: Firebase!
var userFollowingRef: Firebase!
var blockedByUsersRef: Firebase!
var datesRef: Firebase!
var geofireEndRef: Firebase!

var geoFireEnd: GeoFire? {

    return GeoFire(firebaseRef: geofireEndRef)
}

var dateRangeStart = Int()
var dateRangeEnd = Int()

override func viewDidLoad(){
    super.viewDidLoad()

    usersRef = DataService.ds.REF_USERS
    userFollowingRef = DataService.ds.REF_CURRENTUSER_FOLLOWING
    blockedByUsersRef = DataService.ds.REF_BLOCKED_BY_USERS
    datesRef = DataService.ds.REF_DATES
    geofireEndRef = DataService.ds.REF_GEOFIREREF_END
}

override func viewWillAppear(animated: Bool){
    super.viewWillAppear(animated)

    if userdefaultsUid != nil
    {
        geoFireEnd!.getLocationForKey(userID, withCallback: { (location, error) in
            if (error != nil)
            {
                print("An error occurred getting the location for \(self.userID) : \(error.localizedDescription)")

            } else if (location != nil)
            {
                self.updateUsersWithlocation(location)

            } else
            {
                print("GeoFire does not contain a location for \(self.userID)")

                self.updateUsersWithoutLocation()
            }
        })
    }
}

func updateUsersWithlocation(location: CLLocation)
{
    var allKeys = [String]()

    let locationQuery = self.geoFireEnd!.queryAtLocation(location, withRadius: 100.0)

    locationQuery.observeEventType(GFEventType.init(0), withBlock: {(key: String!, location: CLLocation!) in

        allKeys.append(key)

        self.datesRef.queryOrderedByKey().queryStartingAtValue(String(self.dateRangeStart)).queryEndingAtValue(String(self.dateRangeEnd)).observeEventType(.ChildAdded, withBlock: {
            snapshot in

            self.users.removeAll(keepCapacity: true)
            self.newKeys.removeAll()
            self.tableView.reloadData()

            for datesKey in snapshot.children
            {
                self.usersRef.childByAppendingPath(datesKey.key!).observeSingleEventOfType(.Value, withBlock: { snapshot in

                    if let key = datesKey.key where key != self.userID
                    {
                        if  allKeys.contains(key!) {

                            let newuser = FBUser(userKey: key!, dictionary: snapshot.value as! [String : AnyObject])

                            self.blockedByUsersRef.childByAppendingPath(key).childByAppendingPath(self.userID).observeSingleEventOfType(.Value, withBlock: { (snapshot) -> Void in

                                if let _ = snapshot.value as? NSNull
                                {
                                    // we have not blocked  this one
                                    self.blockedByUsersRef.childByAppendingPath(self.userID).childByAppendingPath(key).observeSingleEventOfType(.Value, withBlock: { snapshot in

                                        if let _ = snapshot.value as? NSNull
                                        {
                                            // we are not blocked by this one
                                            if self.newKeys.contains(newuser.userKey) {}
                                            else
                                            {
                                                self.users.append(newuser)
                                                self.newKeys.append(newuser.userKey)
                                            }
                                        }
                                        self.tableView.reloadData()
                                    })
                                }
                            })
                        }
                    }
                })
            }
        })
    })
}

本質上,用戶可以在某個日期在某個地方。 他們確定了到達目的地的日期,如下面的代碼所述。 該日期可能會在該區域之前的7天到之后的21天之間與該區域內的其他用戶重疊。 這些用戶可以被跟蹤,阻止。 但是我讓那些顯示在tableView中。 如果他們將日期或位置設置為其他日期,則會彈出一組不同的用戶。

    if let userStartDate = beginningDate as? Double
    {
        let intUserStartDate = Int(userStartDate)

        dateRangeStart = intUserStartDate - 604800

        dateRangeEnd = intUserStartDate + 1814400

        print(dateRangeStart, intUserStartDate, dateRangeEnd)

        updateUsers()
    }
    else
    {
        updateUsersWithoutDate()
    }

這可能不是答案,也可能根本沒有幫助,但我想把它扔在那里。

假設您確實要尋找兩件事:位置和時間,我們需要一些機制來處理它。

位置更靜態; 即保齡球聯盟將永遠是保齡球聯盟,並且時間是動態的,我們需要一個范圍。 所以,給定一個結構

{
  "events" : {
    "event_0" : {
      "loc_time" : "bowling_5"
    },
    "event_1" : {
      "loc_time" : "tennis_7"
    },
    "event_2" : {
      "loc_time" : "tennis_8"
    },
    "event_3" : {
      "loc_time" : "dinner_9"
    }
  }
}

此結構處理兩個條件。 您可以輕松查詢時間為7的所有具有網球位置的節點。您還可以查詢從開始時間6到結束時間9的網球范圍,這將返回Tennis_7和Tennis_8

這是一些ObjC代碼

Firebase *ref = [self.myRootRef childByAppendingPath:@"events"];

FQuery *query = [[[ref queryOrderedByChild:@"loc_time"] 
                   queryStartingAtValue:@"tennis_6"] queryEndingAtValue:@"tennis_8"];

[query observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@", snapshot);

}];

您可以從中推斷出位置,然后替換為時間的位置和距離或時間戳。

另一種修改(這可能是顯而易見的,但為清楚起見而說明)是使用對您的位置的引用,而不是實際名稱(保齡球,網球);

events
   "event_0" : {
      "loc_time" : "-JAY8jk12998f_20160311140200" // locationRef_timestamp
    },

locations
   -JAY8jk12998f : {
      "loc_name": "Fernando's Hideaway"
   }

以想要獲取數據的方式來結構化數據可以顯着減少代碼(以及查詢中查詢的復雜性等)。

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM