<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Firebase me</title>
    <description>The latest articles on DEV Community by Firebase me (@firebaseme).</description>
    <link>https://dev.to/firebaseme</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F5281%2Fe5e25e16-cd11-46dc-b722-c77bc3132ab4.png</url>
      <title>DEV Community: Firebase me</title>
      <link>https://dev.to/firebaseme</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/firebaseme"/>
    <language>en</language>
    <item>
      <title>Bread in a Jar</title>
      <dc:creator>DIGI Byte</dc:creator>
      <pubDate>Mon, 27 May 2024 02:40:17 +0000</pubDate>
      <link>https://dev.to/firebaseme/bread-in-a-jar-3nah</link>
      <guid>https://dev.to/firebaseme/bread-in-a-jar-3nah</guid>
      <description>&lt;h1&gt;
  
  
  Bread in a Jar: Understanding the Concept
&lt;/h1&gt;

&lt;p&gt;In the world of technology and programming, there's a humorous and enlightening concept known as "duck programming." This idea involves explaining your code or problem to a rubber duck, and in doing so, often revealing the solution to yourself. Similarly, there's a new concept called "bread in a jar" that addresses a common issue faced by many tech enthusiasts and developers. This concept illustrates the scenario where one understands individual components (A and B) or knows how to execute specific tasks but struggles with their correct implementation or integration, often reversing the intended order or logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept Explained
&lt;/h2&gt;

&lt;p&gt;Imagine you have a jar labeled "peanut butter," but instead of containing peanut butter, it's filled with slices of bread. Each slice of bread represents a piece of knowledge or a skill you possess. Instead of spreading peanut butter on bread to make a sandwich, you've put bread inside the peanut butter jar. While the components are related, their implementation is incorrect, leading to confusion and inefficiency.&lt;/p&gt;

&lt;p&gt;This analogy reflects the experience of many developers: you know how to write functions, understand databases, or use APIs, but integrating these components into a cohesive and functional system can be challenging. This mismatch often results from a lack of understanding of the overall system architecture or the interdependencies between different parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples in Programming
&lt;/h2&gt;

&lt;p&gt;Let's explore some examples in programming, particularly using Firebase services, to illustrate this concept further.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Firebase Authentication and Firestore
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Understanding A and B&lt;/strong&gt;: You know how to implement Firebase Authentication to allow users to sign in and how to set up Firestore to store user data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Breakdown&lt;/strong&gt;: You might try to store user data in Firestore before the user is authenticated, leading to issues where data is not properly linked to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Ensure that the user is authenticated first, then use the unique user ID (UID) provided by Firebase Authentication as a key in Firestore to store and retrieve user-specific data. This ensures that each user's data is securely linked to their account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;onAuthStateChanged&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userDocRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;firestore&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;userDocRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// additional user data&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Firebase Cloud Functions and Firestore
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Understanding A and B&lt;/strong&gt;: You can write Firebase Cloud Functions to perform backend logic and know how to read/write data in Firestore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Breakdown&lt;/strong&gt;: You might write Cloud Functions that attempt to modify Firestore data directly without considering the event-driven nature of Cloud Functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use Firestore triggers in your Cloud Functions to listen for specific events (e.g., document creation, update, deletion) and execute the corresponding logic. This approach ensures that your backend logic runs automatically in response to changes in your database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-functions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebase-admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onUserCreate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firestore&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users/{userId}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;snap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Perform actions based on the new user data&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New user created:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Firebase Hosting and Firestore Security Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Understanding A and B&lt;/strong&gt;: You know how to deploy a web app using Firebase Hosting and set up Firestore Security Rules to protect your data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Breakdown&lt;/strong&gt;: You might configure Security Rules that are too restrictive or too lenient, either blocking legitimate access or allowing unauthorized access. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Learn how to use Firestore Security Rules to define fine-grained access controls based on user authentication status and custom claims. By combining Hosting and Security Rules, you can ensure that your web app serves content securely and only to authorized users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firestore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;databases&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/documents &lt;/span&gt;&lt;span class="err"&gt;{
&lt;/span&gt;    &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example Conversation: Bread in a Jar Problem
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Firebase is not working. Help!"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "Alright, did you add your Firebase credentials in the HTML?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Yep, they’re there."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "Did you import and initialize Firebase in your JS?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Is that important?"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Firebase config&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;firebaseConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;authDomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-auth-domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;storageBucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-storage-bucket&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messagingSenderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-messaging-sender-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your-app-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// Initialize Firebase&lt;/span&gt;
&lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initializeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firebaseConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Got it. I missed that part."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "Classic bread-in-a-jar move. Did you set up Firestore too?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Nope. What’s that?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "It's your database. Add this after initializing Firebase:"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;firestore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Okay, added. Anything else?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "Check your Firestore security rules. Sometimes they’re too tight. Here’s a basic one:"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firestore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;databases&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/documents &lt;/span&gt;&lt;span class="err"&gt;{
&lt;/span&gt;    &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="o"&gt;=**&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="nx"&gt;read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dev 1&lt;/strong&gt;: "Thanks! I was totally putting bread in the peanut butter jar."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev 2&lt;/strong&gt;: "No worries. Now spread that peanut butter properly. Let me know if you get stuck again!"&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>debugging</category>
      <category>learning</category>
    </item>
    <item>
      <title>Navigating the Complexities of Firebase App Check and Hosting Channels: A Developer's Odyssey</title>
      <dc:creator>DIGI Byte</dc:creator>
      <pubDate>Mon, 08 Apr 2024 21:26:27 +0000</pubDate>
      <link>https://dev.to/firebaseme/navigating-the-complexities-of-firebase-app-check-and-hosting-channels-a-developers-odyssey-3mpk</link>
      <guid>https://dev.to/firebaseme/navigating-the-complexities-of-firebase-app-check-and-hosting-channels-a-developers-odyssey-3mpk</guid>
      <description>&lt;p&gt;In the dynamic realm of web application development, the integration of security measures with hosting solutions often presents a labyrinth of technical challenges. This narrative becomes particularly intricate when discussing the integration of Firebase App Check with Firebase Hosting channels, especially within the ambit of deploying secure and isolated preview environments. The dialogue between developers qb1t and Greg Fenton, along with inputs from DIGI, unveils the nuanced obstacles and the strenuous journey towards a viable solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq723nx9t8836tygm96bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq723nx9t8836tygm96bg.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Genesis of the Problem
&lt;/h2&gt;

&lt;p&gt;The journey begins with qb1t's quest to implement Firebase Hosting channels alongside Firebase App Check in a manner that ensures robust security. Firebase Hosting offers a streamlined platform for hosting web app content, boasting fast performance and secure delivery. Concurrently, Firebase App Check acts as a guardian, safeguarding Firebase resources from malicious abuse. The crux of qb1t's challenge lies in the integration of these two powerful tools under the constraint of using a custom domain, compounded by the stringent security protocols of reCAPTCHA v3.&lt;/p&gt;

&lt;h3&gt;
  
  
  An Intricate Web of Requirements
&lt;/h3&gt;

&lt;p&gt;qb1t's implementation strategy was sound—using App Check with reCAPTCHA v3 to protect database, storage, and functions, with the custom domain as the sole gatekeeper for requests. This setup should, in theory, provide a fortress of security. However, the deployment of preview channels through GitHub Actions, destined for review in the pull request phase, introduced a critical snag. These previews are relegated to the &lt;code&gt;web.app&lt;/code&gt; domain, stripping away the protective veil of the custom domain and leaving the Firebase resources vulnerable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dialogue of Discovery
&lt;/h2&gt;

&lt;p&gt;Greg Fenton's initial uncertainty about the problem's specifics quickly gave way to a deep dive into potential solutions and workarounds. The conversation evolved, exploring the feasibility of separate Firebase projects for previews and the possibility of configuring App Check to accommodate multiple domains or subdomains. Each proposed solution seemed to brush against the fundamental limitations of Firebase's hosting model or the rigid security model of App Check.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub, a Beacon of Hope?
&lt;/h3&gt;

&lt;p&gt;The discovery of a GitHub issue suggesting the possibility of preview deployment under custom subdomains sparked a momentary glimmer of hope. This lead propelled qb1t into the depths of GitHub Actions documentation, uncovering the potential to specify channel IDs for preview deployments. Yet, this path was fraught with its own set of challenges, including domain redirection issues with registrars like Namecheap and technical limitations around SSL certificates and HTTP redirections.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Resolution, or Lack Thereof
&lt;/h2&gt;

&lt;p&gt;Faced with insurmountable technical barriers and unyielding service limitations, qb1t arrived at a bifurcated strategy—deploying to two distinct Firebase-hosted sites based on the stage of the pull request. This workaround, while functional, underscores the convoluted nature of integrating tightly secured web services with flexible deployment workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflecting on the Journey
&lt;/h3&gt;

&lt;p&gt;This odyssey through the intricacies of Firebase App Check and Hosting channels reveals several critical lessons for the broader developer community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility vs. Security&lt;/strong&gt;: The delicate balance between flexible hosting solutions and rigorous security measures can constrain developers, forcing them into complex workarounds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Power of Community&lt;/strong&gt;: The collaborative exploration of potential solutions highlights the value of community engagement in navigating technical challenges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Continuous Evolution of Web Development&lt;/strong&gt;: This narrative is a testament to the ever-evolving nature of web development, where today's solutions may not fit tomorrow's challenges.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;As Firebase and similar platforms evolve, one hopes for advancements that address these complexities, offering more integrated, secure, and flexible solutions. The dialogue between qb1t, Greg Fenton, and DIGI serves as a beacon for developers navigating the stormy seas of modern web development, illuminating the importance of perseverance, community, and the relentless pursuit of innovation.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
