# Services : Firebase : Python SDK [firebase-admin](https://pypi.org/project/firebase-admin/) — [src](https://github.com/firebase/firebase-admin-python/) | [docs](https://firebase.google.com/docs/reference/admin/python) | [firestore](https://cloud.google.com/python/docs/reference/firestore/latest/google.cloud.firestore_v1.client) ```bash pip install firebase_admin ``` ```python from firebase_admin import auth, credentials, db, firestore, initialize_app from firebase_admin.firestore import DocumentReference, DocumentSnapshot, FieldFilter ``` ## App Initialization Must call `initialize_app()` before other methods. Returns App instance, though you generally won't need it. If you don't specify a name, defaults to `"[DEFAULT]"`. If you need multiple apps, specify a separate name for each. ```python app = initialize_app() # default app, no credentials app = initialize_app( "foo" ) # "foo" app, no credentials app = initialize_app( cred=credentials.Certificate( "path/to/cert.json" ) ) app = initialize_app( cred=credentials.Certificate( json.loads( "...cert..." ) ) ) app = initialize_app( options=dict( projectId="..." ) ) ``` #### Apps & Creds ```python app.credential cred.project_id app.name cred.service_account_email app.options cred.signer app.project_id ``` ## Auth #### API ```python # firebase_admin.auth.<func> create_user( uid # User ID to assign to the newly created user (optional). display_name # The user’s display name (optional). email # The user’s primary email (optional). email_verified # A boolean indicating whether or not the user’s primary email is verified (optional). phone_number # The user’s primary phone number (optional). photo_url # The user’s photo URL (optional). password # The user’s raw, unhashed password. (optional). disabled # A boolean indicating whether or not the user account is disabled (optional). ) -> UserRecord delete_user( uid ) generate_email_verification_link( email # The email of the user to be verified. action_code_settings = None # `ActionCodeSettings` instance (optional). # Defines whether the link is to be handled by a mobile app # and the additional state information to be passed in the deep link. ) -> verification link generate_password_reset_link( email # The email of the user whose password is to be reset. action_code_settings = None # `ActionCodeSettings` instance (optional). # Defines whether the link is to be handled by a mobile app # and the additional state information to be passed in the deep link. ) -> reset link get_user( uid ) -> UserRecord # raises auth.UserNotFoundError get_user_by_email( email ) -> UserRecord # if user not found list_users( page_token = None # Indicates starting point (optional). `None` retrieves the first page of users. max_results = 1000 # 1000 is both the default and the max ) -> ListUsersPage update_user( uid, **kwargs ) -> UserRecord # same kwargs as create_user() verify_id_token( id_token ) -> payload # raises InvalidIdTokenError, ExpiredIdTokenError verify_id_token( id_token, app=None, check_revoked=False, clock_skew_seconds=0 ) ``` #### Objects ```python ListUsersPage get_next_page() iterate_all() # returns iter: ExportedUserRecord that starts on this page has_next_page next_page_token users # [ ExportedUserRecord ] ExportedUserRecord( UserRecord ) password_hash password_salt UserRecord( UserInfo ) custom_claims dict | None disabled bool display_name str | None email str | None email_verified bool phone_number str | None photo_url str | None provider_data [ UserInfo ] provider_id str tenant_id str | None tokens_valid_after_timestamp int uid str user_metadata UserMetadata UserInfo display_name email phone_number photo_url provider_id uid UserMetadata creation_timestamp int last_refresh_timestamp int | None last_sign_in_timestamp int ``` ## Database #### API ```python # firebase_admin.db.<func> reference( path="/", app=None, url=None ) -> Reference # example ref = db.reference( "/"[, url="https://DBNAME.firebaseio.com"] ) ``` #### Objects ```python Reference child( path ) -> Reference delete() get( shallow=False ) -> object listen( callback ) -> ListenerRegistration order_by_child( path ) -> Query order_by_key() -> Query order_by_value() -> Query push( value="" ) -> Reference adds child node to object with unique key set( value ) update( value ) value = map of paths and values key parent path ListenerRegistration .close() Event .data parsed JSON # new data or None if deleted .event_type "put" | "patch" .path # path relative to reference Query <chaining methods> equal_to( value ) start_at( start ) end_at( end ) limit_to_first( limit ) limit_to_last( limit ) <other> get() -> object ``` ## Firestore ### API ```python client = firestore.client() ``` **Get a Single Document** ```python doc = client.collection( "cities" ).document( "foo" ).get() if doc.exists: print( f"Document data: { doc.to_dict() }" ) else: print( "No such document!" ) ``` **Get Multiple Documents** ```python for doc in client.collection( "cities" ).where( "capital", "==", True ).stream(): print( f"{ doc.id } => { doc.to_dict() }" ) ``` **Get All Documents** ```python for doc in client.collection( "cities" ).stream(): print( f"{ doc.id } => { doc.to_dict() }" ) ``` ### Objects From experience.... ```python collection.document( id ) -> DocumentReference collection.stream() -> iter: DocumentSnapshot # DocumentReference and DocumentSnapshot each link to the other - 1:1 relationship dr.get() -> ds ds.reference -> dr # You can call .document() with a non-existant ID and get back a DocumentReference, # then call .get() on that and get a DocumentSnapshot, with no errors raised. # With a non-existant DocumentSnapshot: ds.exists -> False ds.to_dict() -> None ``` **Query/Collection** ```python base_query. BaseQuery( ... ) order_by( "FIELD", direction="ASCENDING" ) -> BaseQuery recursive() -> BaseQuery select( ... ) where( "FIELD", "OP", VALUE -or- filter=Fieldfilter( "FIELD", "OP", VALUE ) ) -> BaseQuery query. Query( parent <- CollectionReference projection <- ??? field_filters <- tuple( ??? ) orders <- tuple( ??? ) ) < BaseQuery get -> list onSnapshot( CALLABLE ) -> Watch CALLABLE( docs, changes, read_time ) stream -> iter: DocumentSnapshot # stream() preferred over get() avg/count/sum base_collection. BaseCollectionReference id parent document( ... ) -> DocumentReference select( ... ) where( ... ) order_by( ... ) avg/count/sum collection. CollectionReference < BaseCollectionReference[Query] add( document_data, document_id=None, ... ) -> ( timestamp, DocumentReference ) list_documents -> iter: DocumentReference ``` **Documents** ```python base_document. BaseDocumentReference id parent path collection( ... ) document. DocumentReference < BaseDocumentReference collections( ... ) create( ... ) delete( ... ) get() -> DocumentSnapshot on_snapshot( ... ) set( ... ) update( ... ) base_document. DocumentSnapshot create_time exists -> bool id reference -> DocumentReference to_dict() -> dict update_time ``` *Add/Create/Update* ```python coll.add( document_data: dict, document_id=None, retry=..., timeout=None ) dr.create( document_data: dict, retry=..., timeout=None ) # raises Conflict if already exists dr.set( document_data: dict, merge=False, retry=..., timeout=None ) merge=False replace if exists, create if it doesn't merge=True merge if exists, create if doesn't dr.update( field_updates: dict, option=None, retry=..., timeout=None ) By default, verifies document exists before making updates. field_updates { "foo": { "bar": 42 } } # sets document[ "foo" ] to { "bar": 42 } { "foo.bar": 42 } # sets document[ "foo" ][ "bar" ] to 42 { "foo": firestore.DELETE_FIELD } # deletes document[ "foo" ] { "foo": firestore.SERVER_TIMESTAMP } # deletes document[ "foo" ] WARNING: Paths ("foo.bar") can only be used at the top leve. ```