Các method để lấy dữ liệu

- setValue: viết dữ liệu đến một path được định nghĩa ....

updateChildValues: Cập nhật giá trị đã tồn tại trong dữ liệu trong cơ sở dữ liệu của bạn.

- childByAutoId: Tự động tạo ra một id là duy nhất trong cơ sở dữ liệu. Mỗi lần bạn gọi childByAutoId cơ sở dữ liệu của bạn tạo ra một id duy nhất  URL dạng messages/users/<unique-user-id>/<username>

- runTransactionBlock: sử dụng  func này khi làm việc với dữ liệu phức tạp có thể bị ảnh hưởng bởi việc cập nhật đồng thời.

Sửng dụng setValue 

-Cách cơ bản để cơ sở dữ liệu ghi đó là setValue, nó lưu dữ liệu mới đến cở sở dữ liệu được khai báo theo URL, với phương thức này nó sẽ thay bất kỳ dữ liệu nào đã có tại đường dẫn đó.  Với phương thức này chúng ta sẽ sử dụng khi mà đã có sắn một key mà chúng ta không muốn tạo thêm một key nữa và sau đó mới đẩy dữ liệu lên. Để hiểu rõ hơn về setValue, chúng ta sẽ xây dựng một blogging app đơn giản. Dữ liệu cho app của chúng ta sẽ được lưu tại đường link dưới đây:

Obj-C

Firebase *ref = [[Firebase alloc] initWithUrl:@"https://docs-examples.firebaseio.com/web/saving-data/fireblog"];

Swift

var ref = Firebase(url: "https://docs-examples.firebaseio.com/web/saving-data/fireblog")

Chúng ta hãy cùng bắt đầu bằng việc lưu dữ liệu vài user. Chúng ta sẽ định danh mỗi user trong cơ sở dữ liệu bằng một username là duy nhất, và chúng ta sẽ thêm fullname và birthday. Khi mà mỗi user có một username là duy nhất, nó sẽ tạo điều kiện cho chúng ta sử dụng setValue bằng cách lấy username là key.

Đầu tiên, chúng ta bắt đầu tạo một dictionary của các user chúng ta muốn lưu ở database. Chúng ta sẽ tạo một tham chiếu là dữ liệu của user rồi sau đó gọi setValue để lưu một đối tượng user với username, fullname, birthday. Chúng ta có thể truyền vào dictionary với setValue.

OBJ-C

  

NSDictionary *alanisawesome = @{

      @"full_name" : @"Alan Turing",

      @"date_of_birth": @"June 23, 1912"

  };

  NSDictionary *gracehop = @{

      @"full_name" : @"Grace Hopper",

      @"date_of_birth": @"December 9, 1906"

  };

  Firebase *usersRef = [ref childByAppendingPath: @"users"];

  NSDictionary *users = @{

      @"alanisawesome": alanisawesome,

      @"gracehop": gracehop

  };

  [usersRef setValue: users];

SWIFT

  

var alanisawesome = ["full_name": "Alan Turing", "date_of_birth": "June 23, 1912"]

  var gracehop = ["full_name": "Grace Hopper", "date_of_birth": "December 9, 1906"]



  var usersRef = ref.childByAppendingPath("users")



  var users = ["alanisawesome": alanisawesome, "gracehop": gracehop]

  usersRef.setValue(users)

Khi mà dictionary ở trên được lưu vào database, các thuộc tính sẽ tự động được ánh xạ đến một vị trí có dạng lồng nhau. Bây giờ các bạn có thể kiểm tra URL:https://docs-examples.firebaseio.com/web/saving-data/fireblog/users/alanisawesome/full_name

Chúng ta sẽ thấy kết quả là "Alan Turing" hoặc bạn cũng có thể lưu dữ liệu trực tiếp đến một vị trí con:

OBJC-C

//ở đây chúng ta append them path rồi sau đó set value tại vị trí đó

Firebase *alanRef = [usersRef childByAppendingPath: @"alanisawesome"];

[alanRef setValue: alanisawesome];



Firebase *hopperRef = [usersRef childByAppendingPath: @"gracehop"];

[hopperRef setValue: gracehop];

SWIFT

//ở đây chúng ta append them path rồi sau đó set value tại vị trí đó

usersRef.childByAppendingPath("alanisawesome").setValue(alanisawesome)

usersRef.childByAppendingPath("gracehop").setValue(gracehop)

Cả 2 ví dụ ở trên,  cả 2 giá trị đều là kiểu dictionary và ghi chúng tới 2 vị trí con khác nhau, kết quả sau khi chúng ta save thành công vào 

database:

{

  "users": {

    "alanisawesome": {

      "date_of_birth": "June 23, 1912",

      "full_name": "Alan Turing"

   },

    "gracehop": {

      "date_of_birth": "December 9, 1906",

      "full_name": "Grace Hopper"

    }

  }

}

Nếu dữ liệu đã có tại biến usersRef, thì method đầu tiên sẽ viết đè lên nó còn với method 2 thì sẽ chính sửa lại giá trị của mỗi nhánh con và các nhanh con khác không bị thay đổi.

Chú ý: Sử dụng setValue sẽ viết đè dữ liệu tại vị trí xác định, bao gồm mọi nhánh con.

Cập nhật dữ liệu đã lưu

Nếu bạn muôn viết nhiều nhánh con cho một database tại cùng một thời điểm mà không muốn viết đè lên dữ liệu đã tồn tại, bạn có thể sử dụng updateChildValue như dưới đây:

OBJ-C

Firebase *hopperRef = [usersRef childByAppendingPath: @"gracehop"];

NSDictionary *nickname = @{

    @"nickname": @"Amazing Grace",

};

[hopperRef updateChildValues: nickname];

SWIFT

var hopperRef = usersRef.childByAppendingPath("gracehop")

var nickname = ["nickname": "Amazing Grace"]

hopperRef.updateChildValues(nickname)

Nó sẽ cập nhật dữ liệu của "Grace" bao gồm nickname. Nếu chúng ta đã sử dụng setValue ở đây thay cho updateChildValues, nó sẽ delete cả full_name và date_of_birth từ "hopperRef".

Hơn nữa Firebase hỗ trợ update với đường dẫn. Nó có nghĩa là method updataChildValues có thể cập nhật giá trị tại nhiều vị trí trong cơ sở dữ liệu Firebase của bạn tại cùng một thời điểm. Việc sử dụng cập nhật bằng đường dẫn như ở dưới đây sẽ có thể thêm các nickname đến cả "Grace" and "Alan" tại cùng một thời điểm:

 OBJ-C

[usersRef updateChildValues: @{

  @"alanisawesome/nickname": @"Alan The Machine",

  @"gracehop/nickname": @"Amazing Grace"

}];

SWIFT

usersRef.updateChildValues([

  "alanisawesome/nickname": "Alan The Machine",

  "gracehop/nickname": "Amazing Grace"

])

Sau khi cập nhật, cả "Alan" và "Grace" sẽ có các nickname mới:

{

  "users": {

    "alanisawesome": {

      "date_of_birth": "June 23, 1912",

      "full_name": "Alan Turing",

      "nickname": "Alan The Machine"

    },

    "gracehop": {

      "date_of_birth": "December 9, 1906",

      "full_name": "Grace Hopper",

      "nickname": "Amazing Grace"

    }

  }

}

Chú ý: Việc cập nhật đối tượng bằng cách viết các đối tượng với path là cha mà không truy cập đến vị trí cụ thể của con thì sẽ cho ra kết quả khác. Cùng xem điều gì sẽ xảy ra nếu chúng ta cố gắng cập nhật "Grace" và "Alan" theo cách này:

OBJ-C

[usersRef updateChildValues: @{

  @"alanisawesome": @{

    @"nickname": @"Alan The Machine"

  },

  @"gracehop": @{

    @"nickname": @"Amazing Grace"

  }

}];

SWIFT

usersRef.updateChildValues([

  "alanisawesome": [

    "nickname": "Alan The Machine"

  ],

  "gracehop": [

    "nickname": "Amazing Grace"

  ]

])

Kết quả trả về sẽ khác các bạn có thể thấy dữ liệu đã bị ghi đè:

{

  "users": {

    "alanisawesome": {

      "nickname": "Alan The Machine"

    },

    "gracehop": {

      "nickname": "Amazing Grace"

    }

  }

}

Chú ý: Việc xác định một đường dẫn key như “alanisawesome”, updateChildValue chỉ cập nhật dữ liệu tại chính cấp độ của nó, và mọi dữ liệu sẽ bị viết đè giống như khi sử dụng setValue. Firebase cho phép sử dụng dường dẫn dài “alanisawesome/nickname” được sử dụng để tránh việc ghi đè dữ liệu.

Thêm một Completion Block

Nếu bạn muốn biết khi nào dữ liệu của bạn đã được đẩy lên thành công, bạn có thể thêm một completion block. Cả setValueupdateChildValues có một optional completion lock nó được gọi khi viết thành công đến database. Việc cung cấp optional này cho phép theo dõi việc lưu trữ dữ liệu cũng như biết liệu dữ liệu có được đồng bộ hay không. Nếu không thành công thì nó sẽ lắng nghe và đẩy ra một đối tượng lỗi để chỉ rõ tại sao không lưu được dữ liệu.

Lưu các danh sách với childByAutoID

Đỗi với các ví dụ trên ta tạo ra các key thủ công theo tên user nhưng đôi khi cũng có các user trùng tên nên nó không còn là duy nhất nửa để không phải lo lắng về vấn đề tạo ra key Firebase đã cung cấp cho chúng ta childByAutoId nó tự sinh ra một id duy nhất khi một nhánh con gọi và thêm vào tham chiếu của database. Bằng việc sử dụng key nhánh con duy nhất cho mỗi thành phần mới trong list , thì nhiều client có thể thêm các nhánh con vào cùng một vị trí trong cũng một thời điểm là không lo lắng về việc xung đột.

OBJ-C

Firebase *postRef = [ref childByAppendingPath: @"posts"];

NSDictionary *post1 = @{

    @"author": @"gracehop",

    @"title": @"Announcing COBOL, a New Programming Language"

};

Firebase *post1Ref = [postRef childByAutoId];

[post1Ref setValue: post1];

NSDictionary *post2 = @{

    @"author": @"alanisawesome",

    @"title": @"The Turing Machine"

};

Firebase *post2Ref = [ref childByAutoId];

[post2Ref setValue: post2];

SWIFT

let postRef = ref.childByAppendingPath("posts")

let post1 = ["author": "gracehop", "title": "Announcing COBOL, a New Programming Language"]

let post1Ref = postRef.childByAutoId()

post1Ref.setValue(post1)

let post2 = ["author": "alanisawesome", "title": "The Turing Machine"]

let post2Ref = postRef.childByAutoId()

post2Ref.setValue(post2)

Dữ liệu sẽ có dạng như sau:

{

  "posts": {

    "-JRHTHaIs-jNPLXOQivY": {

      "author": "gracehop",

      "title": "Announcing COBOL, a New Programming Language"

     },

    "-JRHTHaKuITFIhnj02kE": {

      "author": "alanisawesome",

      "title": "The Turing Machine"

    }

  }

}

 Sử dụng childByAutoId để lấy ID duy nhất

Việc gọi childByAutoId sẽ trả về một tham chiếu mới đến đường dẫn dữ liệu mới, bạn có thể sử dụng để lấy giá trị của ID và set cho dữ liệu:

OBJ-C

NSDictionary *post1 = @{

    @"author": @"gracehop",

    @"title": @"Announcing COBOL, a New Programming Language"

};

Firebase *post1Ref = [ref childByAutoId];

[post1Ref setValue: post1];

NSString *postId = post1Ref.key;

SWIFT

var post1 = ["author": "gracehop", "title": "Announcing COBOL, a New Programming Language"]

var post1Ref = ref.childByAutoId()

post1Ref.setValue(post1)

var postId = post1Ref.key

Bạn có thể thấy việc gọi key từ tham chiếu của childByAutoId sẽ lấy được Id là kiểu chuỗi.

Lưu dữ liệu phức tạp

Khi bạn làm việc với dữ liệu phức tạp, nó có thể bị lỗi bởi việc chính sử cùng một thời điểm, như là việc tăng biến đếm, Firebase cung cập một cách truyền dữ liệu đi. Bạn có thể chọn method này với 2 tham số một là function cập nhất và một là ontional completion block, cái function cập nhật lấy được trạng thái của dữ liệu hiện tại nó là một tham số được trả về. Ví dụ, bạn muốn tăng biến đếm các bài viết của blog, bạn sẽ làm như sau:

OBJ-C

Firebase *upvotesRef = [[Firebase alloc] initWithUrl: @"https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes"];

[upvotesRef runTransactionBlock:^FTransactionResult *(FMutableData *currentData) {

    NSNumber *value = currentData.value;

    if (currentData.value == [NSNull null]) {

        value = 0;

    }

    [currentData setValue:[NSNumber numberWithInt:(1 + [value intValue])]];

    return [FTransactionResult successWithValue:currentData];

}];

SWIFT

var upvotesRef = Firebase(url: "https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes")

upvotesRef.runTransactionBlock({

    (currentData:FMutableData!) in

    var value = currentData.value as? Int

    if !value {

        value = 0

    }

    currentData.value = value! + 1

    return FTransactionResult.successWithValue(currentData)

})

Chúng ta sử dụng curentValue.Value để xem nếu dữ liệu trả về là null có nghĩa là chưa có ai vote bài viết đó, method này có thể trả về null nếu không có giá trị mặc định.Nếu chúng ta không sử dụng function transaction và ví dụ có 2 client cùng tang lượt vote cùng lúc thì kết quả trả về sẽ là 1 thay vì là 2 cái này khá giống sync.  

Nguồn bài viết:https://www.firebase.com

Demo ứng dụng chơi cờ online sử dụng Firebase:

Tham khảo:

Hiện nay tại TechMaster đang có 3 khóa học về lập trình iOS, một khóa dạy bằng ngôn ngữ Objective-C, một khóa bằng ngôn ngữ Swift và một khoá Swift - Kết nối REST Web Service. Hình thức học tập rất linh hoạt cho bạn lựa chọn và sẽ có mức học phí khác nhau tùy theo bạn chọn học online, offline hoặc FlipLearning (kết hợp giữa online và offline). Ngoài ra bạn cũng có thể tham gia thực tập toàn thời gian tại TechMaster để rút ngắn thời gian học và nhanh chóng đi kiếm việc làm.