๐Ÿ”ฅFirebase Integration

Adding user Data to the Firebase Database

Firebase is a popular choice for Authentication and Data Storage. To get started with Firebase refer to the doc here Firebase Integration.

Databutton offers built-in storage within its workspace, supported by Databutton's own SDK. This storage is ideal for small-scale production apps and quick testing purposes. Read more here Data storage

To store data over Firestore Database:

  1. Set up the Firestore Client.

  2. Create API (backend) to handle the data storage

Read more about creating API in Databutton here.

Setting up the Firestore Client

  • Start with creating a new project and register the app using the "Web" option ( follow the instructions in details as mentioned earlier here Setting up the Firestore Client)

  • On the left-hand side tab, under the "Build" dropdown -> Select the "Firestore Database" option

  • Select the "Create database" option

  • In the "Select a location" step, choose the nearest Google Cloud region to your application's users, then click the "Next" button ( this step can't be reverted back once created )

  • Select "Production" or "Test" mode (based on the usage).

  • Generate Service Account Key ( follow the step below )

    • Go to the Firebase Console.

    • Click on the gear icon next to "Project Overview" and select "Project settings".

    • Navigate to the "Service accounts" tab.

    • Click "Generate new private key" and download the JSON file.

  • Copy the credentials from the downloaded JSON file.

Creating an API (Python backend) to handle the data storage

  • Ask Databutton on how to store the Service account key credetials

Example prompt ( while doing via the Databutton's Agent )

I already have the firebase Service Account Key credentials.
I would like to store as a secret in Databutton Storage.
  • Alternatively, you can manually store the Service account key details ( recommended and quick )

    • Go to the config section in the menu ( Top menu bar in Databutton's workspace -> Select Config โš™๏ธ )

  • Next, prompting the architecture of the firestore database. This step is cruical and varies based on the app in mind. Here's an example of a simpler use case :

Each user needs to be stored via it's email.
So the email is the top most of the hirerarchy.
Under each email, there needs to be two fields.
A) url
B) content

Make sure, the url and content section is appended everytime.

The API model needs three inputs -- email, url and content
Output should be a sucess message when stored.

Note, this step can be iterative, and it's very important to reciprocate the database architecture concisely. It is also recommended to test and iterate further!

Here's an example code snippet based on the database architecure discussed :

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from google.cloud import firestore
import databutton as db
import json
FIRESTORE_CREDENTIALS = db.secrets.get("FIRESTORE_CREDENTIALS")
credentials_dict = json.loads(FIRESTORE_CREDENTIALS)
firestore_client = firestore.Client.from_service_account_info(credentials_dict)

# Router for endpoints
router = APIRouter()

# Define the input model for the data
class UserData(BaseModel):
    email: str
    url: str
    content: str

# Endpoint to store user data in Firestore
@router.post("/store-user-data")
def store_user_data(data: UserData):
    try:
        # Reference to the user's document
        doc_ref = firestore_client.collection("users").document(data.email)
        # Retrieve existing data
        doc = doc_ref.get()
        if doc.exists:
            existing_data = doc.to_dict()
            urls = existing_data.get("urls", [])
            contents = existing_data.get("contents", [])
        else:
            urls = []
            contents = []
        # Append new data
        urls.append(data.url)
        contents.append(data.content)
        # Update the document
        doc_ref.set({
            "urls": urls,
            "contents": contents
        })
        print(f"Data stored for user: {data.email}")
        return {"message": "User data stored successfully"}
    except firestore.exceptions.GoogleCloudError as e:
        print(f"Firestore error: {e}")
        raise HTTPException(status_code=500, detail="Firestore error")
    except Exception as e:
        print(f"Unexpected error: {e}")
        raise HTTPException(status_code=500, detail="Unexpected error")

Last updated