<?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: Jeishanul Haque Shishir</title>
    <description>The latest articles on DEV Community by Jeishanul Haque Shishir (@jeishanul).</description>
    <link>https://dev.to/jeishanul</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%2Fuser%2Fprofile_image%2F2340053%2F9b8cebe9-f659-4ccf-a14c-f9e3561e20de.jpg</url>
      <title>DEV Community: Jeishanul Haque Shishir</title>
      <link>https://dev.to/jeishanul</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeishanul"/>
    <language>en</language>
    <item>
      <title>🧠 Advanced Error Handling &amp; Monitoring in Laravel APIs: Patterns, Pitfalls, and the Under-Documented Truths</title>
      <dc:creator>Jeishanul Haque Shishir</dc:creator>
      <pubDate>Sun, 26 Oct 2025 15:05:22 +0000</pubDate>
      <link>https://dev.to/jeishanul/advanced-error-handling-monitoring-in-laravel-apis-patterns-pitfalls-and-the-2oi2</link>
      <guid>https://dev.to/jeishanul/advanced-error-handling-monitoring-in-laravel-apis-patterns-pitfalls-and-the-2oi2</guid>
      <description>&lt;h1&gt;
  
  
  ⚡ Laravel API Error Handling — Beyond the Defaults
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Laravel’s default error handling works fine — &lt;em&gt;until&lt;/em&gt; your API hits real-world complexity.&lt;br&gt;
In this guide, we’ll go beyond the docs — into &lt;strong&gt;advanced exception handling&lt;/strong&gt;, &lt;strong&gt;structured JSON responses&lt;/strong&gt;, &lt;strong&gt;contextual logging&lt;/strong&gt;, and &lt;strong&gt;proactive monitoring&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚨 Why Error Handling in Laravel APIs Deserves a Second Look
&lt;/h2&gt;

&lt;p&gt;Laravel’s built-in error handling is great for local dev — but once your API scales or hits production, the defaults start to fail you.&lt;/p&gt;

&lt;p&gt;Most developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔄 Rely solely on &lt;code&gt;Handler.php&lt;/code&gt; for everything&lt;/li&gt;
&lt;li&gt;📜 Log errors without real monitoring&lt;/li&gt;
&lt;li&gt;❌ Forget to standardize JSON error responses&lt;/li&gt;
&lt;li&gt;⚠️ Leak stack traces or inconsistent messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; confused clients, hidden failures, and an avalanche of meaningless “something went wrong” logs.&lt;br&gt;
Let’s fix that.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚙️ 1. Understand What You’re Actually Handling
&lt;/h2&gt;

&lt;p&gt;Before you touch &lt;code&gt;Handler.php&lt;/code&gt;, build a clear &lt;strong&gt;mental model&lt;/strong&gt; of the three error types your Laravel API will face:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🟢 Operational errors&lt;/strong&gt; — predictable issues like a missing user, invalid token, or failed validation.&lt;br&gt;
These are &lt;strong&gt;client-side fixable&lt;/strong&gt; problems. Return a &lt;strong&gt;structured JSON&lt;/strong&gt; response to guide correction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🟠 Programmer errors&lt;/strong&gt; — bugs in your code (null properties, undefined methods, logic errors).&lt;br&gt;
They should &lt;strong&gt;never&lt;/strong&gt; reach production. Log them and fix the root cause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔴 Infrastructure errors&lt;/strong&gt; — external failures like DB timeouts, Redis crashes, or API outages.&lt;br&gt;
The client can’t fix them, so don’t blame them. Use &lt;strong&gt;retries, circuit breakers, or alerts&lt;/strong&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mental shortcut:&lt;/strong&gt; decide whether to &lt;strong&gt;return&lt;/strong&gt;, &lt;strong&gt;log&lt;/strong&gt;, or &lt;strong&gt;alert&lt;/strong&gt; — never lump all exceptions together.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 2. Structure Your JSON Error Responses (Stop Returning Random Stuff)
&lt;/h2&gt;

&lt;p&gt;Here’s a &lt;strong&gt;battle-tested&lt;/strong&gt; JSON structure that keeps clients happy and your logs clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USER_NOT_FOUND"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The specified user does not exist."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"req_78x1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-26T12:34:56Z"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;💡 Why it works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Predictable for clients&lt;/li&gt;
&lt;li&gt;⚙️ Machine-readable for apps&lt;/li&gt;
&lt;li&gt;🧱 Extensible — add &lt;code&gt;trace_id&lt;/code&gt;, &lt;code&gt;docs_link&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧰 Laravel Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;renderable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&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="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api/*'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'error'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s1"&gt;'code'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;class_basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;method_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'getStatusCode'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getStatusCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&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;
  
  
  🧱 3. Leverage &lt;code&gt;withExceptions()&lt;/code&gt; in Laravel 12+
&lt;/h2&gt;

&lt;p&gt;Laravel 12 quietly introduced a cleaner, centralized way to handle exceptions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withExceptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$exceptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$exceptions&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;renderable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ValidationException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'error'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'code'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'VALIDATION_ERROR'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="s1"&gt;'status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;422&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="mi"&gt;422&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;🔥 Why it matters&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more &lt;code&gt;Handler.php&lt;/code&gt; chaos&lt;/li&gt;
&lt;li&gt;Keeps API error logic modular and maintainable&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 4. Logging ≠ Monitoring — Know the Difference
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If you’re only logging, you’re already too late.&lt;/strong&gt;&lt;br&gt;
Logs tell you what &lt;em&gt;happened.&lt;/em&gt; Monitoring tells you &lt;em&gt;when and why.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🪵 Logging Best Practices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add context: user ID, route, payload&lt;/li&gt;
&lt;li&gt;Use multiple channels (&lt;code&gt;daily&lt;/code&gt;, &lt;code&gt;slack&lt;/code&gt;, &lt;code&gt;sentry&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Use proper levels (&lt;code&gt;error&lt;/code&gt;, &lt;code&gt;critical&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;reportable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'API Exception'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'exception'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;get_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'user_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fullUrl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'method'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;method&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;
  
  
  📈 Monitoring Best Practices
&lt;/h3&gt;

&lt;p&gt;Set &lt;strong&gt;alert thresholds&lt;/strong&gt;, not just log entries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚨 5% error rate in 5 minutes → alert&lt;/li&gt;
&lt;li&gt;⚙️ Queue failures &amp;gt; N → alert&lt;/li&gt;
&lt;li&gt;⏱️ External API latency &amp;gt; 500ms → alert&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommended stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧪 Local: Laravel Telescope&lt;/li&gt;
&lt;li&gt;🧠 Exceptions: Sentry / Bugsnag / Flare&lt;/li&gt;
&lt;li&gt;📡 Metrics &amp;amp; uptime: Better Stack / Datadog / New Relic&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚠️ 5. Common Pitfalls Most Developers Miss
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;💀 Using &lt;code&gt;dd()&lt;/code&gt; in production — breaks JSON output.&lt;/li&gt;
&lt;li&gt;🔓 Leaking sensitive data — always set &lt;code&gt;APP_DEBUG=false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🔁 Inconsistent error structures — breaks API contracts.&lt;/li&gt;
&lt;li&gt;🕳️ Ignoring infra-level failures — missing DB or Redis logs.&lt;/li&gt;
&lt;li&gt;🧩 No API versioning — schema changes break old clients.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Treat your error structure as part of your &lt;strong&gt;public API contract&lt;/strong&gt; — version it like any other endpoint.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 6. Bonus: Exception-to-Code Mapping
&lt;/h2&gt;

&lt;p&gt;Give each domain exception its own stable code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserNotFoundException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getErrorCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'USER_NOT_FOUND'&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;Then in your handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;method_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'getErrorCode'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getErrorCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;class_basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&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;Benefit:&lt;/strong&gt; every error gets a &lt;strong&gt;consistent, predictable&lt;/strong&gt; code the frontend can depend on.&lt;/p&gt;




&lt;h2&gt;
  
  
  📡 7. Add Correlation IDs for Cross-Service Debugging
&lt;/h2&gt;

&lt;p&gt;Distributed systems demand traceability. Add a &lt;code&gt;request_id&lt;/code&gt; for every call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$requestId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;withContext&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'request_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$requestId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'X-Request-ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$requestId&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;Now every log, job, or service can be linked through a single trace ID 🔍.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧾 8. Your Production-Ready Checklist
&lt;/h2&gt;

&lt;p&gt;✅ Consistent JSON response format&lt;br&gt;
✅ Domain-specific exception classes&lt;br&gt;
✅ Multi-channel logging + alerting&lt;br&gt;
✅ Error budgets &amp;amp; metrics tracking&lt;br&gt;
✅ &lt;code&gt;APP_DEBUG=false&lt;/code&gt; in production&lt;br&gt;
✅ Correlation IDs for traceability&lt;br&gt;
✅ Versioned error contracts&lt;/p&gt;

&lt;p&gt;If you’ve got all of these — your API is &lt;strong&gt;mature, observable, and resilient&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;Laravel gives you the &lt;strong&gt;tools&lt;/strong&gt; — but production-grade stability comes from what the docs don’t teach:&lt;br&gt;
&lt;strong&gt;structured error contracts, contextual logging, and real-time observability.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal isn’t to eliminate errors.&lt;br&gt;
It’s to make every error &lt;strong&gt;actionable&lt;/strong&gt;, &lt;strong&gt;traceable&lt;/strong&gt;, and &lt;strong&gt;non-catastrophic&lt;/strong&gt;. 🚀&lt;/p&gt;




</description>
      <category>laravel</category>
      <category>php</category>
      <category>backend</category>
      <category>api</category>
    </item>
    <item>
      <title>🔔 How to Send Push Notifications in Laravel with Firebase Cloud Messaging (FCM)</title>
      <dc:creator>Jeishanul Haque Shishir</dc:creator>
      <pubDate>Wed, 02 Jul 2025 17:46:14 +0000</pubDate>
      <link>https://dev.to/jeishanul/how-to-send-push-notifications-in-laravel-with-firebase-cloud-messaging-fcm-25de</link>
      <guid>https://dev.to/jeishanul/how-to-send-push-notifications-in-laravel-with-firebase-cloud-messaging-fcm-25de</guid>
      <description>&lt;p&gt;&lt;strong&gt;Learn how to integrate Firebase Cloud Messaging (FCM) with Laravel to send real-time web and mobile push notifications.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Push notifications have become an essential tool for increasing user engagement and retention. Whether you're building a mobile app or a progressive web app (PWA), sending real-time alerts is crucial. In this comprehensive guide, you'll learn how to set up Laravel Firebase push notifications using Firebase Cloud Messaging (FCM)—step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Why Use Firebase with Laravel?
&lt;/h2&gt;

&lt;p&gt;Firebase Cloud Messaging is a free and reliable cross-platform solution from Google that enables you to send notifications and messages to devices. Laravel, being a powerful PHP framework, can easily integrate with Firebase, allowing your backend to trigger web push notifications and mobile alerts to individual users or groups.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you’ll have a working setup that supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Laravel backend sending FCM push notifications.&lt;/li&gt;
&lt;li&gt;Web clients receiving real-time browser alerts.&lt;/li&gt;
&lt;li&gt;Storing and managing FCM tokens in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📋 Prerequisites&lt;/strong&gt;&lt;br&gt;
Before you dive into the code, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Laravel 8 or higher installed.&lt;/li&gt;
&lt;li&gt;A Firebase account (&lt;a href="https://console.firebase.google.com" rel="noopener noreferrer"&gt;Firebase Console&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Composer, Node.js, and npm installed.&lt;/li&gt;
&lt;li&gt;Basic understanding of PHP, Laravel, and JavaScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🔧 Step 1: Set Up Firebase Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.1 Create a Firebase Project&lt;/strong&gt;&lt;br&gt;
Head to the &lt;a href="https://console.firebase.google.com" rel="noopener noreferrer"&gt;Firebase Console&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Click on Add Project, name it (e.g., &lt;strong&gt;ExampleApp&lt;/strong&gt;), and follow the prompts.&lt;/p&gt;

&lt;p&gt;Take note of the Project ID under Project &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2 Generate Service Account Key&lt;/strong&gt;&lt;br&gt;
Go to &lt;strong&gt;Settings &amp;gt; Service Accounts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click Generate new private key.&lt;/p&gt;

&lt;p&gt;Rename and store the downloaded JSON file as &lt;strong&gt;firebase_credentials.json&lt;/strong&gt; in &lt;strong&gt;storage/app/firebase/&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3 Add a Web App&lt;/strong&gt;&lt;br&gt;
In the Firebase console, go to Project &lt;strong&gt;Settings &amp;gt; General&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;&amp;lt;/&amp;gt;&lt;/strong&gt; icon to add a web app and copy the config object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "apiKey": "your-api-key",
  "authDomain": "your-auth-domain",
  "projectId": "your-project-id",
  "storageBucket": "your-storage-bucket",
  "messagingSenderId": "your-messaging-sender-id",
  "appId": "your-app-id",
  "measurementId": "your-measurement-id"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1.4 Retrieve the VAPID Key&lt;/strong&gt;&lt;br&gt;
Under &lt;strong&gt;Cloud Messaging &amp;gt; Web Push certificates&lt;/strong&gt;, copy your &lt;strong&gt;Public&lt;/strong&gt; Key &lt;strong&gt;(VAPID key)&lt;/strong&gt;. You'll need this in the frontend.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚙️ Step 2: Configure Laravel Project
&lt;/h2&gt;

&lt;p&gt;2.1 Add Environment Variables&lt;br&gt;
Update your &lt;strong&gt;.env&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FIREBASE_CREDENTIALS=app/firebase/firebase_credentials.json
FIREBASE_PROJECT_ID=example-app
FIREBASE_VAPID_KEY=your-vapid-key-here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.2 Update config/services.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'firebase' =&amp;gt; [
    'credentials' =&amp;gt; storage_path(env('FIREBASE_CREDENTIALS')),
    'project_id' =&amp;gt; env('FIREBASE_PROJECT_ID'),
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.3 Modify Users Table for FCM Tokens&lt;/strong&gt;&lt;br&gt;
Run the migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan make:migration add_fcm_token_to_users_table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in the migration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schema::table('users', function (Blueprint $table) {
    $table-&amp;gt;string('fcm_token')-&amp;gt;nullable();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan migrate

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.4 Install Google Auth Library&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require google/auth

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡 Step 3: Create Firebase Notification Service
&lt;/h2&gt;

&lt;p&gt;Create a service class app/Services/Notifications/FireBase.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Services\Notifications;

use Exception;
use Google\Auth\Credentials\ServiceAccountCredentials;
use GuzzleHttp\Client;

class FireBase
{
    public static function send($heading, $message, $deviceIds, $data = [])
    {
        $deviceIds = array_values(array_filter($deviceIds));
        if (empty($deviceIds)) {
            throw new Exception('No device IDs provided');
        }

        $scopes = ['https://www.googleapis.com/auth/firebase.messaging'];
        $credentials = new ServiceAccountCredentials($scopes, config('services.firebase.credentials'));
        $accessToken = $credentials-&amp;gt;fetchAuthToken()['access_token'];
        $projectId = config('services.firebase.project_id');

        $messagePayload = [
            'notification' =&amp;gt; [
                'title' =&amp;gt; $heading,
                'body' =&amp;gt; $message,
            ],
            'android' =&amp;gt; [
                'priority' =&amp;gt; 'high',
                'notification' =&amp;gt; [
                    'sound' =&amp;gt; 'default',
                ],
            ],
            'apns' =&amp;gt; [
                'payload' =&amp;gt; [
                    'aps' =&amp;gt; [
                        'sound' =&amp;gt; 'default',
                    ],
                ],
            ],
        ];

        if (!empty($data)) {
            $messagePayload['data'] = $data;
        }

        $messagePayload += count($deviceIds) &amp;gt; 1
            ? ['tokens' =&amp;gt; $deviceIds]
            : ['token' =&amp;gt; $deviceIds[0]];

        $payload = ['message' =&amp;gt; $messagePayload];
        $url = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send";

        $client = new Client();

        return $client-&amp;gt;request('POST', $url, [
            'headers' =&amp;gt; [
                'Authorization' =&amp;gt; 'Bearer ' . $accessToken,
                'Accept' =&amp;gt; 'application/json',
                'Content-Type' =&amp;gt; 'application/json',
            ],
            'json' =&amp;gt; $payload,
        ]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🖥️ Step 4: Frontend Setup for Web Push Notifications
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;4.1 Add Firebase Messaging Script&lt;/strong&gt;&lt;br&gt;
In your Blade template (layouts/app.blade.php):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="module"&amp;gt;
    import { initializeApp } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-app.js";
    import { getMessaging, getToken, onMessage } from "https://www.gstatic.com/firebasejs/11.0.1/firebase-messaging.js";

    const firebaseConfig = {
        apiKey: "your-api-key",
        authDomain: "your-auth-domain",
        projectId: "your-project-id",
        storageBucket: "your-storage-bucket",
        messagingSenderId: "your-messaging-sender-id",
        appId: "your-app-id",
        measurementId: "your-measurement-id"
    };

    const app = initializeApp(firebaseConfig);
    const messaging = getMessaging(app);

    async function initFirebaseMessagingRegistration() {
        try {
            const permission = await Notification.requestPermission();
            if (permission === 'granted') {
                const token = await getToken(messaging, {
                    vapidKey: "{{ env('FIREBASE_VAPID_KEY') }}"
                });

                if (token) {
                    await axios.post("{{ route('firebase.token') }}", {
                        _method: "PATCH",
                        fcm_token: token
                    });
                }
            }
        } catch (err) {
            console.error("FCM Token error:", err);
        }
    }

    onMessage(messaging, ({ notification }) =&amp;gt; {
        new Notification(notification.title, {
            body: notification.body
        });
    });

    initFirebaseMessagingRegistration();
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.2 Create the Service Worker&lt;/strong&gt;&lt;br&gt;
Save this as &lt;strong&gt;public/firebase-messaging-sw.js&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;importScripts("https://www.gstatic.com/firebasejs/8.3.2/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/8.3.2/firebase-messaging.js");

firebase.initializeApp({
    apiKey: "your-api-key",
    authDomain: "your-auth-domain",
    projectId: "your-project-id",
    storageBucket: "your-storage-bucket",
    messagingSenderId: "your-messaging-sender-id",
    appId: "your-app-id",
    measurementId: "your-measurement-id",
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage(({ data: { title, body, icon } }) =&amp;gt; {
    self.registration.showNotification(title, { body, icon });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📩 Store FCM Tokens in Database
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create Route and Controller&lt;/strong&gt;&lt;br&gt;
Route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::patch('/firebase/token', [App\Http\Controllers\FirebaseController::class, 'updateToken'])-&amp;gt;name('firebase.token');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class FirebaseController extends Controller
{
    public function updateToken(Request $request)
    {
        Auth::user()-&amp;gt;update(['fcm_token' =&amp;gt; $request-&amp;gt;fcm_token]);
        return response()-&amp;gt;json(['success' =&amp;gt; true]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✉️ Sending Laravel Push Notifications via Firebase
&lt;/h2&gt;

&lt;p&gt;You can now send notifications using the &lt;strong&gt;FireBase&lt;/strong&gt; service class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use App\Services\Notifications\FireBase;

FireBase::send(
    'Hello User!',
    'This is your Laravel Firebase push notification.',
    ['user-fcm-token-here'],
    ['customKey' =&amp;gt; 'customValue']
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ Troubleshooting Common Issues
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Notification Permission Denied: Make sure users allow browser notifications.&lt;/li&gt;
&lt;li&gt;Invalid Token: Check if FCM tokens are correctly stored.&lt;/li&gt;
&lt;li&gt;Firebase Errors: Double-check your API key, VAPID key, and service account JSON.&lt;/li&gt;
&lt;li&gt;403 or Auth Errors: Ensure the Firebase service account JSON is correctly set and readable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📢 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Setting up Laravel push notifications with Firebase Cloud Messaging unlocks a powerful toolset for improving user experience. Whether you're targeting mobile apps or web browsers, FCM and Laravel make a reliable and scalable combination.&lt;/p&gt;

&lt;p&gt;✅ Now you’re ready to build apps that notify your users instantly and keep them engaged!&lt;/p&gt;

&lt;h3&gt;
  
  
  📬 Contact
&lt;/h3&gt;

&lt;p&gt;For any questions, support, or collaboration, feel free to reach out through the following channels:&lt;/p&gt;

&lt;p&gt;📧 Email: &lt;a href="//mailto:shishirjeishanul@gmail.com"&gt;shishirjeishanul@gmail.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 WhatsApp: Chat on &lt;a href="https://wa.link/rundct" rel="noopener noreferrer"&gt;WhatsApp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 GitHub (Main Profile): &lt;a href="https://github.com/jeishanul" rel="noopener noreferrer"&gt;github.com/jeishanul&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📦 Project Repository: &lt;a href="https://github.com/jeishanul/LaravelFirebaseNotification" rel="noopener noreferrer"&gt;Laravel Firebase Notification on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>firebase</category>
      <category>php</category>
      <category>fcm</category>
    </item>
  </channel>
</rss>
