เริ่มต้นไปที่ firebase google (ต้องใช้ google account)
firebase คือ อะไร ไปอ่านเวปนี้ ref. เวปนี้จะเน้นไปทาง java
สร้าง project ขึ้นมาก่อน (google ให้เราสร้างได้ฟรี 25 projects)
click ที่ Database ก็จะมีหน้าตาประมาณนี้ ส่วนที่จะเอาไปใช้คือ ลิงค์
[ https://sample-app-a1e7f.firebaseio.com/ ] แต่ละคน จะได้ส่วนนี้แตกต่างกันไป
ลิงค์นี้คือ ส่วนที่เอาไว้เรียกใช้งาน
แต่โดย default ตรง Ruls (กฎ) จะไม่ยอมให้คนอื่น acces ได้เลย ดังนั้น เราต้องเข้าไปแก้ไขซะ
เบื้องต้นก็แก้ให้เป็น true ให้หมดไปก่อน
อ่านที่เวปนี้ เขียนอธิบายไว้ละเอียด ref.
ตัวอย่างข้อมูล ก็จะได้หน้าตาประมาณนี้ เป็น JSON
ทดสอบว่าสามารถใช้งานได้ สามารถเรียกดูได้จาก
https://sample-app-a2e7f.firebaseio.com/mydata.json
ต่อมาในส่วนของ python
ขั้นแรก import firebase package ตอนนี้ มีอยู่ 3 แหล่งที่ทาง google แนะนำ ref
1. python-firebase by Özgür Vatansever
ลง package ที่ต้องจำเป็นก่อนที่จะใช้งานตัวนี้คือ requests
$ sudo pip install requests
$ sudo pip install python-firebase
$ sudo pip install python-firebase-gae
** ตัวนี้ถ้าไปใช้กับ google appengine standard จะมีปัญหา เนื่องจากไม่ support multi processor ให้ติดตั้ง python-firebase อีกตัวแทนดูรายละเอียดได้ที่ https://github.com/b4oshany/python-firebase-gae/
ใน code python ให้เพิ่ม 2 บรรทัดนี้ลงไป
from firebase import firebase firebase = firebase.FirebaseApplication('https://sample-app-x.firebaseio.com', None)
ตรงส่วนสีแดง ก็ใส่ URL link ของตัวเองลงไป
วิธีเขียนข้อมูลลง DB ref
PUT กับ POST ใช้ต่างกันยังไง
- PUT จะต้องระบุ key
- POST จะสร้าง random key ให้
เช่น
result = firebase.post(id, data['comment'])firebase จะ random key ให้
/id -Kq7rSDsQRXWKAVu0phH: "comment"หากอยากระบุ key ของตัวเอง และ ให้ firebase สร้าง key ให้
result = firebase.post(id,{'comment': 'mycomment'})ได้ nested JSON
/id -Kq7swawlLJlz07VEBFT comment: "mycomment"กรณี PUT จะต้องระบุ key ให้ด้วย
result = firebase.put(id,'comment',{'msg': 'mycomment'})จะได้ผลลัพธ์แบบนี้
/id -comment msg: "mycomment"ถ้าอ้างอิง id , comment เดิม ข้อมูลที่ put ลงมาจะเขียนทับ ข้อมูลเก่า
PATCH ใช้ update key ที่ระบุไว้ โดยไม่กระทบ กับ ข้อมูลส่วนอื่น
DELETE เอาไว้ลบข้อมูล
firebase.delete(id, 'comment')
วิธีการเรียกอ่านข้อมูล GET ref
result = firebase.get('/users', '1')ใส่ option {'print': 'pretty'} เพื่อให้ ผลออกมาอ่านได้ง่ายขึ้น
result = firebase.get('/users/2', None, {'print': 'pretty'}, {'X_FANCY_HEADER': 'VERY FANCY'})ลองเอา URL นี้วางใน browser https://sample-app-a1e7f.firebaseio.com/mydata.json
จะได้ผลออกมาแบบนี้ ซึ่งอ่านยากมาก
ลองเพิ่ม option print = pretty
https://sample-app-a1e7f.firebaseio.com/mydata.json?print=pretty
จะได้ผลออกมาแบบนี้ ซึ่งอ่านง่ายกว่าเยอะ
Authentication
from firebase import firebase firebase = firebase.FirebaseApplication('https://your_storage.firebaseio.com', authentication=None) result = firebase.get('/users', None, {'print': 'pretty'}) print result {'error': 'Permission denied.'} authentication = firebase.Authentication('THIS_IS_MY_SECRET', 'ozgurvt@gmail.com', extra={'id': 123}) firebase.authentication = authentication print authentication.extra {'admin': False, 'debug': False, 'email': 'ozgurvt@gmail.com', 'id': 123, 'provider': 'password'} user = authentication.get_user() print user.firebase_auth_token "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhZG1pbiI6IGZhbHNlLCAiZGVidWciOiBmYWxzZSwgIml hdCI6IDEzNjE5NTAxNzQsICJkIjogeyJkZWJ1ZyI6IGZhbHNlLCAiYWRtaW4iOiBmYWxzZSwgInByb3ZpZGVyIjog InBhc3N3b3JkIiwgImlkIjogNSwgImVtYWlsIjogIm96Z3VydnRAZ21haWwuY29tIn0sICJ2IjogMH0.lq4IRVfvE GQklslOlS4uIBLSSJj88YNrloWXvisRgfQ" result = firebase.get('/users', None, {'print': 'pretty'}) print result {'1': 'John Doe', '2': 'Jane Doe'}เมื่อ sign-in ด้วย email,password ใช้ function Authentication เพื่อ ให้ firebase สร้าง token สำหรับใช้ตรวจสอบว่ากับ rule ว่ามีสิทธิ์มั้ย
authentication = firebase.Authentication('password', 'email', extra={'id': 123})ดูค่าที่ทาง server return กลับมา
print authentication.extra {'admin': False, 'debug': False, 'email': 'ozgurvt@gmail.com', 'id': 123, 'provider': 'password'}provider คือ attribute ที่บอกว่า เรา authen ด้วยวิธีใด
เนื่องจาก firebase รองรับ multi provider คือ login ด้วย google , facebook .. สามารถมี accout id เดียวกันได้ id คือ ตัวบอกว่า login ด้วยวิธีนี้ แล้วจะได้ id อะไร
2. Pyrebase by Jame childs-maidment
* ควรใช้กับ python3 หากใช้กับ python2 อาจจะมีข้อผิดพลาดpip install pyrebaseเรียกใช้
import pyrebase config = { "apiKey": "apiKey", "authDomain": "projectId.firebaseapp.com", "databaseURL": "https://databaseName.firebaseio.com", "storageBucket": "projectId.appspot.com", "serviceAccount": "path/to/serviceAccountCredentials.json" } firebase = pyrebase.initialize_app(config)serviceAccount ไว้สำหรับเมื่อ admin login เข้ามาสามารถใช้งานได้โดยไม่สน rule ที่ประกาศใน firebase
วิธีการ create serviceAccountCredentials ref
1. เข้าไปที่หน้า firebase console แล้วเลือก setting (รูปเฟือง) > users and permissions
2. เลือก Service accounts
3. ที่ฝั่งขวา เลือก firebase-adminsdk แล้วกด create key
4. เมื่อได้ไฟล์มา เอาไปวางไว้ที่ server เพื่อ เรียกใช้ (ตัวอย่าง ส่วนหนึ่ง)
Pyrebase เรียกใช้ firebase service ได้ถึง 3 (python-firebase ได้แค่ database , authen)
- firebase.auth() - Authentication
- firebase.database() - Database
- firebase.storage() - Storage
Authentication
sign_in_with_email_and_password() จะส่ง user data และ token เพื่อใช้กับ firebase rule# Get a reference to the auth service
auth = firebase.auth()
# Log the user in
user = auth.sign_in_with_email_and_password(email, password)
# Get a reference to the database service
db = firebase.database()
# data to save
data = {
"name": "Mortimer 'Morty' Smith"
}
# Pass the user's idToken to the push method
results = db.child("users").push(data, user['idToken'])
ระบุ user['idToken'] ด้วยเพื่อให้มี สิทธิ์ในการ writeปกติ token จะ expire ภายใน 1 ชม. ดังนั้นหากมีการใช้อยู่ให้เรา refresh ใหม่เรื่อยๆ
user = auth.sign_in_with_email_and_password(email, password)
# before the 1 hour expiry:
user = auth.refresh(user['refreshToken'])
# now we have a fresh token
user['idToken']
Manage User
create user ที่ใช้ email /passwordauth.create_user_with_email_and_password(email, password)* ต้อง enable sign-in method ที่ firebase dashboard ด้วย
Verifying emails
auth.send_email_verification(user['idToken'])
Sending password reset emails
auth.send_password_reset_email("email")
Get account information
auth.get_account_info(user['idToken'])
Database
- Save data
ใช้ child() method ในการสร้าง path ลงไปในแต่ละ level (google support 32 levels)db = firebase.database() db.child("users").child("Morty")push : ใช้เก็บข้อมูลที่ต้องไม่ซ้ำ สร้าง key อัตโนมัติ, timestamp-based key
data = {"name": "Mortimer 'Morty' Smith"} db.child("users").push(data)set : เมื่อต้องการระบุ key ของตัวเอง key ที่ระบุคือ "Morty"
data = {"name": "Mortimer 'Morty' Smith"} db.child("users").child("Morty").set(data)update : อัพเดทข้อมูลที่มีอยู่แล้ว
db.child("users").child("Morty").update({"name": "Mortiest Morty"})remove : ลบข้อมูลที่มีอย่แล้ว
db.child("users").child("Morty").remove()
multi-location updates : อัพเดทพร้อมกับหลายที่
data = { "users/Morty/": { "name": "Mortimer 'Morty' Smith" }, "users/Rick/": { "name": "Rick Sanchez" } } db.update(data)
ใช้ push อัพเดทพร้อมกันหลายที่ต้องใช้คู่กับ generate_key() method.
data = { "users/"+db.generate_key(): { "name": "Mortimer 'Morty' Smith" }, "users/"+db.generate_key(): { "name": "Rick Sanchez" } } db.update(data)
- Retrieve data
val : เมื่อได้ object มา ใช้ val() ในการkey : method key() เรียกค่า key อย่างเดียวusers = db.child("users").get()print(users.val())# {"Morty": {"name": "Mortimer 'Morty' Smith"},"Rick": {"name": "Rick Sanchez"}}
ดึงเฉพาะ value จาก attribute ที่ต้องการ
print(users.val()["name"])
#{ Mortimer 'Morty' Smith ,
# Rick Sanchez }
user = db.child("users").get() print(user.key()) # userseach : ดึงค่าออกมาเป็น list แล้วใช้ key() , val() แสดงค่าอีกที
all_users = db.child("users").get() for user in all_users.each(): print(user.key()) # Morty print(user.val()) # {name": "Mortimer 'Morty' Smith"} print(user.val()["name"])get : ดึงค่าจาก path ทั้งหมด
shallow : ดึงเฉพาะ ค่า key ออกมาเท่านั้นall_users = db.child("users").get()
all_user_ids = db.child("users").shallow().get() # {"Morty", "Rick"}* shallow() ใช้ร่วมกับ complex querie ไม่ได้
streaming : จับการเปลี่ยนแปลงของข้อมูลทันที ที่มีการเปลี่ยน
def stream_handler(message): print(message["event"]) # put print(message["path"]) # /-K7yGTTEp7O549EzTYtI print(message["data"]) # {'title': 'Pyrebase', "body": "etc..."} my_stream = db.child("posts").stream(stream_handler)อย่างน้อยควรจะ put หรือ patch ข้อมูลด้วย Streaminig from the REST API
ถ้ามีการทำ multiple stream ควรระบุ stream_id ด้วย
close the streammy_stream = db.child("posts").stream(stream_handler, stream_id="new_posts")
my_stream.close()
Complex Queries
Queries สามารถใช้ method ต่อกันได้เรื่อยๆusers_by_name = db.child("users").order_by_child("name").limit_to_first(3).get()
ผลลัพธ์จะได้ 3 users แรกเรียงตามชื่อorder_by_child : เรียงตาม level ที่กำหนด ตาม key
users_by_name = db.child("users").order_by_child("name").get()
equal_to : คืนค่าที่มี value ตามที่กำหนดusers_by_score = db.child("users").order_by_child("score").equal_to(10).get()
คืนค่า users ที่มี score เท่ากับ 10start_at and end_at : ระบุ range ของข้อมูล
users_by_score = db.child("users").order_by_child("score").start_at(3).end_at(10).get()
คืนค่า users เรียงตาม score ที่มี score อยู่ระหว่าง 3-10limit_to_first and limit_to_last : limit ข้อมูลที่รับ
users_by_score = db.child("users").order_by_child("score").limit_to_first(5).get()
order_by_key : เรียง key ตาม ascending (น้อยไปมาก)users_by_key = db.child("users").order_by_key().get()
order_by_value : เรียงตาม valueusers_by_value = db.child("users").order_by_value().get()
Storage
ใช้เก็บข้อมูลรูปภาพ ไฟล์child : ระบุ path ที่จะใช้เก็บ
storage.child("images/example.jpg")
put : รับ path จาก local file และ ใส่ token เป็น option ได้storage = firebase.storage() # as admin storage.child("images/example.jpg").put("example2.jpg") # as user storage.child("images/example.jpg").put("example2.jpg", user['idToken'])หากรับ filename มาจาก <input type="file" name="image" />
ตอนรับข้อมูลให้ส่ง request.files.get('image') มาให้ put
storage.child("images/example.jpg").put(request.files.get('image'))
download : ดึงข้อมูลมาเก็บลง local และ สามารถเปลี่ยนชื่อได้
storage.child("images/example.jpg").download("downloaded.jpg")
get_url : คืนค่า url สำหรับ access ผ่าน httpstorage.child("images/example.jpg").get_url()
# https://firebasestorage.googleapis.com/v0/b/storage-url.appspot.com/o/images%2Fexample.jpg?alt=media
generate_key : db.generate_key() ใช้ตาม Firebase's key generation algorithmsort : ปกติ เราจะใช้ orderby แต่ถ้าเราต้องการเรียงอีกที ให้ใช้ sort() method
.
articles = db.child("articles").order_by_child("date").start_at(startDate).end_at(endDate).get() articles_by_likes = db.sort(articles, "likes")
*Storage ยังไม่มี method delete()