--- title: "Getting Started with fireData" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Getting Started with fireData} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` ## Introduction fireData provides an R interface to common operations in selected Google Firebase services, enabling you to: - Store and retrieve data from **Firebase Realtime Database** - Store and query documents in **Cloud Firestore** - Authenticate users with email/password, Google OAuth, or anonymous login - Upload and download files from **Cloud Storage** The package focuses on common REST operations for these four services. It does not cover every Firebase product or every advanced endpoint; see [Firebase feature support](https://github.com/Kohze/fireData/blob/master/inst/FIREBASE-SUPPORT.md). ## Installation ```{r install} # Install from CRAN (when available) install.packages("fireData") # Or install development version from GitHub # install.packages("pak") pak::pak("Kohze/fireData") ``` ## Setup ### 1. Create a Firebase Project 1. Go to [Firebase Console](https://console.firebase.google.com) 2. Click "Add project" and follow the setup wizard 3. Once created, go to Project Settings (gear icon) ### 2. Get Your Credentials From the Firebase Console, you'll need: - **Project ID**: Found in Project Settings > General - **API Key**: Found in Project Settings > General > Web API Key - **Database URL**: Found in Realtime Database section (for RTDB) ### 3. Configure fireData There are several ways to configure fireData: **Option A: Environment Variables (Recommended for production)** ```{r env-vars} Sys.setenv(FIREBASE_PROJECT_ID = "your-project-id") Sys.setenv(FIREBASE_API_KEY = "your-api-key") Sys.setenv(FIREBASE_DATABASE_URL = "https://your-database-url") Sys.setenv(FIREBASE_STORAGE_BUCKET = "your-project-id.firebasestorage.app") ``` **Option B: Configuration File** Configuration files use the following format: ```yaml default: project_id: your-project-id api_key: your-api-key database_url: https://your-database-url storage_bucket: your-project-id.firebasestorage.app ``` **Option C: Interactive Wizard** The wizard configures the current session by default. Saving requires `save = TRUE` and an explicit file path; the parent directory must exist. ```{r wizard} library(fireData) if (interactive()) { firebase_config_wizard() # Optional: save a configuration file in the temporary directory config_file <- tempfile(fileext = ".yml") firebase_config_wizard(save = TRUE, path = config_file) unlink(config_file) } ``` ## Quick Start ### Create a Connection ```{r connection} library(fireData) # Create connection (uses config from environment/file) conn <- firebase_connect() # Or with explicit values conn <- firebase_connect( project_id = "my-project", api_key = "AIzaSy...", database_url = "https://your-database-url", storage_bucket = "my-project.firebasestorage.app" ) print(conn) ``` ## Realtime Database The Realtime Database stores data as one large JSON tree. It's great for simple data structures and real-time sync. ### Store Data ```{r store-data} # Push data with auto-generated key path <- rtdb_push(conn, "messages", list( text = "Hello from R!", author = "R User", timestamp = as.character(Sys.time()) )) print(path) # "messages/-NxYz123..." # Set data at specific path (overwrites) rtdb_set(conn, "users/user123", list( name = "John Doe", email = "john@example.com" )) # Update specific fields (merge) rtdb_update(conn, "users/user123", list( lastLogin = as.character(Sys.time()) )) ``` ### Retrieve Data ```{r retrieve-data} # Get data from path user <- rtdb_get(conn, "users/user123") print(user$name) # Get all messages messages <- rtdb_get(conn, "messages") # Query with filtering results <- rtdb_query(conn, "users") |> query_order_by("name") |> query_limit_to_first(10) |> query_execute() ``` ### Delete Data ```{r delete-data} rtdb_delete(conn, "messages/-NxYz123") ``` ## Cloud Firestore Cloud Firestore is a flexible, scalable NoSQL database. Unlike the Realtime Database, Firestore stores data in **documents** organized into **collections**, making it better for complex, structured data. ### When to Use Firestore vs Realtime Database | Feature | Realtime Database | Cloud Firestore | |---------|------------------|-----------------| | Data model | Large JSON tree | Documents in collections | | Queries | Limited filtering | Rich queries with multiple filters | | Scaling | Limited | Automatic, global | | Offline support | Basic | Advanced | | Best for | Simple data, real-time sync | Complex data, advanced queries | ### Basic Operations ```{r firestore-basic} # Authenticate first (Firestore requires auth) result <- auth_sign_in(conn, "user@example.com", "password") conn <- firebase_set_token(conn, result) # Create/overwrite a document firestore_set(conn, "users", "user123", list( name = "John Doe", email = "john@example.com", age = 30, active = TRUE )) # Add document with auto-generated ID result <- firestore_add(conn, "messages", list( text = "Hello Firestore!", timestamp = Sys.time() )) print(result$.id) # Auto-generated document ID # Get a document user <- firestore_get(conn, "users", "user123") print(user$name) # Update specific fields (without overwriting entire document) firestore_update(conn, "users", "user123", list( lastLogin = Sys.time(), loginCount = 42 )) # Delete a document firestore_delete(conn, "users", "user123") ``` ### Listing Documents ```{r firestore-list} # List all documents in a collection result <- firestore_list(conn, "users", page_size = 50) for (user in result$documents) { print(paste(user$name, "-", user$email)) } # Paginate through large collections result <- firestore_list(conn, "users", page_size = 10) while (!is.null(result$nextPageToken)) { # Process result$documents result <- firestore_list(conn, "users", page_size = 10, page_token = result$nextPageToken) } ``` ### Querying Documents Firestore supports powerful queries with multiple filters: ```{r firestore-query} # Query with filters results <- firestore_query(conn, "products") |> fs_where("price", "<", 100) |> fs_where("inStock", "==", TRUE) |> fs_order_by("price", "asc") |> fs_limit(20) |> fs_execute() for (product in results) { print(paste(product$name, "- $", product$price)) } # Available filter operators: # "==" (equal), "!=" (not equal) # "<", "<=", ">", ">=" (comparisons) # "array-contains", "array-contains-any" # "in", "not-in" # Select specific fields only results <- firestore_query(conn, "users") |> fs_select("name", "email") |> fs_limit(100) |> fs_execute() ``` ### Subcollections Firestore supports nested data with subcollections: ```{r firestore-subcollections} # Add a post to a user's posts subcollection firestore_add(conn, "users/user123/posts", list( title = "My First Post", content = "Hello world!", created = Sys.time() )) # List posts in subcollection posts <- firestore_list(conn, "users/user123/posts") ``` ## Authentication ### Email/Password Login ```{r auth-email} # Sign in result <- auth_sign_in(conn, email = "user@example.com", password = "password123" ) # Update connection with token conn <- firebase_set_token(conn, result) # Now authenticated requests work rtdb_get(conn, "protected/data") firestore_get(conn, "private", "doc1") ``` ### Create New User ```{r auth-create} result <- auth_create_user(conn, email = "newuser@example.com", password = "securepassword" ) ``` ### Anonymous Login ```{r auth-anon} result <- auth_anonymous(conn) conn <- firebase_set_token(conn, result) ``` ## Cloud Storage ```{r storage} # Upload file result <- storage_upload(conn, file_path = "local/image.jpg", object_name = "images/photo.jpg" ) print(result$url) # Download file dest_file <- tempfile(fileext = ".jpg") storage_download(conn, "images/photo.jpg", dest_file) unlink(dest_file) # List files files <- storage_list(conn, prefix = "images/") # Get download URL url <- storage_get_url(conn, "images/photo.jpg") ``` ## Working with Data Frames fireData seamlessly handles R data frames: ```{r dataframes} # Upload mtcars dataset to Realtime Database rtdb_push(conn, "datasets", mtcars) # Download as data frame data <- rtdb_get(conn, "datasets/-KeyHere") # It's still a data frame! head(data) ``` ## Error Handling fireData provides informative error messages: ```{r errors} tryCatch({ auth_sign_in(conn, "wrong@email.com", "badpassword") }, error = function(e) { message("Authentication failed: ", e$message) }) ``` ## Next Steps - Visit the [GitHub repository](https://github.com/Kohze/fireData) for more examples - Check out the [Firebase Documentation](https://firebase.google.com/docs) for detailed API information - See the package help: `?fireData` for a complete function reference