PHPackages                             badawy24/pushify - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. badawy24/pushify

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

badawy24/pushify
================

Laravel multi-provider push notification package with Firebase and OneSignal support.

1.0.1(1mo ago)061MITPHPPHP ^8.2

Since Apr 27Pushed 1mo agoCompare

[ Source](https://github.com/backend-2022/pushify)[ Packagist](https://packagist.org/packages/badawy24/pushify)[ Docs](https://github.com/backend-2022/pushify)[ RSS](/packages/badawy24-pushify/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (3)Used By (0)

Pushify
=======

[](#pushify)

[![Latest Version on Packagist](https://camo.githubusercontent.com/87a319d4db08a56ea512a1195960f267f25a2796ba83f74f38b9f4c12f118363/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f62616461777932342f707573686966792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/badawy24/pushify) [![PHP Version](https://camo.githubusercontent.com/0137db7634f2bfb58931a1788223a4a9136100008a2ee84e758b20b9c6ec21a0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d626c75653f7374796c653d666c61742d737175617265)](https://www.php.net) [![Laravel Version](https://camo.githubusercontent.com/d595a13461fa4fb5ff354efcf503be0ab4b47a805ead05c98e29a1bd428294ae/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d25354531322e302d7265643f7374796c653d666c61742d737175617265)](https://laravel.com) [![License: MIT](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)](LICENSE)

> Laravel backend package for sending push notifications through one selected provider at a time.

Supported providers:

ProviderScheduling🔥 Firebase Cloud Messaging (FCM)Via scheduled command📣 OneSignalNative `send_after`---

Project Structure
-----------------

[](#project-structure)

```
pushify/
├── config/
│   └── pushify.php
├── database/
│   └── migrations/
│       └── 2026_01_01_000000_create_pushify_notifications_table.php
├── routes/
│   └── pushify.php
├── src/
│   ├── Commands/
│   │   └── SendScheduledPushifyNotifications.php
│   ├── Contracts/
│   │   ├── PushifyProviderInterface.php
│   │   └── PushifyServiceInterface.php
│   ├── Factories/
│   │   └── PushifyProviderFactory.php
│   ├── Http/
│   │   ├── Controllers/
│   │   │   └── PushifyController.php
│   │   ├── Requests/
│   │   │   └── StorePushifyRequest.php
│   │   └── Resources/
│   │       └── PushifyResource.php
│   ├── Models/
│   │   └── Pushify.php
│   ├── Providers/
│   │   ├── FirebaseProvider.php
│   │   └── OneSignalProvider.php
│   ├── Services/
│   │   ├── FirebaseService.php
│   │   ├── OneSignalService.php
│   │   └── PushifyService.php
│   └── PushifyServiceProvider.php
├── stubs/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   └── PushifyController.stub
│   │   ├── Requests/
│   │   │   └── StorePushifyRequest.stub
│   │   └── Resources/
│   │       └── PushifyResource.stub
│   └── routes/
│       └── pushify.stub
└── composer.json

```

---

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Publish](#publish)
- [Migration](#migration)
- [Configuration](#configuration)
- [Routes](#routes)
- [Usage](#usage)
- [Notification Statuses](#notification-statuses)
- [Scheduled Command](#scheduled-command)
- [Customizing the HTTP Layer](#customizing-the-http-layer)
- [Adding a Custom Provider](#adding-a-custom-provider)
- [Store Endpoint Payload](#store-endpoint-payload)
- [Response Structure](#response-structure)
- [Authors](#authors)
- [License](#license)

---

Requirements
------------

[](#requirements)

- PHP &gt;= 8.2
- Laravel &gt;= 12.0
- OpenSSL PHP extension *(required for Firebase JWT signing — no external Google SDK needed)*

---

Installation
------------

[](#installation)

```
composer require badawy24/pushify
```

Then clear the cache:

```
php artisan optimize:clear
```

---

Publish
-------

[](#publish)

### Publish everything at once

[](#publish-everything-at-once)

```
php artisan vendor:publish --tag=pushify
```

This publishes only the files you are expected to edit:

```
config/pushify.php
routes/pushify.php
app/Http/Controllers/Pushify/PushifyController.php
app/Http/Requests/Pushify/StorePushifyRequest.php
app/Http/Resources/Pushify/PushifyResource.php

```

> Core services, providers, factories, models, commands, and contracts stay inside the package and are never published.

### Publish separately

[](#publish-separately)

```
# Config only
php artisan vendor:publish --tag=pushify-config

# Routes only
php artisan vendor:publish --tag=pushify-routes

# Controller, Request, Resource
php artisan vendor:publish --tag=pushify-http
```

---

Migration
---------

[](#migration)

```
php artisan migrate
```

Creates the `pushify_notifications` table:

```
id, title, body, image, data, scheduled_at,
status, sent_at, failed_at, error_message,
created_at, updated_at

```

---

Configuration
-------------

[](#configuration)

Published config file: `config/pushify.php`

Only one provider is active at a time, selected from `.env`.

### 🔥 Firebase

[](#-firebase)

```
PUSHIFY_PROVIDER=firebase
FIREBASE_CREDENTIALS=storage/firebase/firebase.json
```

Place your Firebase service account JSON file at `storage/firebase/firebase.json`.

Firebase sends to a topic — default is `all`. Configure it in the published config:

```
'firebase' => [
    'topic' => 'all',
],
```

> Your mobile app must subscribe devices to the same topic.

### 📣 OneSignal

[](#-onesignal)

```
PUSHIFY_PROVIDER=onesignal
ONESIGNAL_APP_ID=your-app-id
ONESIGNAL_API_KEY=your-api-key
ONESIGNAL_API_URL=https://api.onesignal.com/notifications
```

OneSignal sends to `included_segments => ['All']`.

### Optional

[](#optional)

```
# Log full request payload — disable in production
PUSHIFY_LOG_PAYLOAD=false

# Disable package routes if you prefer to define your own
PUSHIFY_ROUTES_ENABLED=true

# Change the route prefix (default: pushify)
PUSHIFY_ROUTE_PREFIX=pushify
```

---

Routes
------

[](#routes)

The package registers these routes automatically:

```
GET  /pushify                  List all notifications (paginated)
POST /pushify                  Create and send
GET  /pushify/{pushify}        Show one
POST /pushify/{pushify}/send   Send an existing notification

```

Check registered routes:

```
php artisan route:list | grep pushify
```

### Adding Auth Middleware

[](#adding-auth-middleware)

After publishing, open `routes/pushify.php` and update the middleware:

```
Route::prefix(config('pushify.routes.prefix', 'pushify'))
    ->middleware(['api', 'auth:sanctum'])
    ->group(function () {
        // routes...
    });
```

---

Usage
-----

[](#usage)

### Inject the service interface

[](#inject-the-service-interface)

```
use Badawy\Pushify\Contracts\PushifyServiceInterface;
```

The package binds this interface automatically — **no manual binding required**.

---

### Send immediately

[](#send-immediately)

```
use Badawy\Pushify\Contracts\PushifyServiceInterface;

class OfferController extends Controller
{
    public function notify(PushifyServiceInterface $push)
    {
        $notification = $push->sendToAll(
            title: 'New offer',
            body: 'Check our latest offers now',
            data: [
                'type'     => 'offer',
                'offer_id' => 15,
            ],
            image: 'https://example.com/image.jpg',
            scheduledAt: null,
        );

        return response()->json($notification);
    }
}
```

Both Firebase and OneSignal send immediately when `scheduledAt` is `null`.

---

### Schedule a notification

[](#schedule-a-notification)

```
$notification = $push->sendToAll(
    title: 'Upcoming sale',
    body: 'Our sale starts in one hour',
    data: ['type' => 'sale'],
    image: null,
    scheduledAt: now()->addHour()->toDateTimeString(),
);
```

ProviderBehavior🔥 FirebaseSaved as `pending` — sent by the command when `scheduled_at create([
    'title'        => 'Draft notification',
    'body'         => 'Notification body',
    'data'         => ['type' => 'general'],
    'image'        => null,
    'scheduled_at' => null,
]);
```

Saved as `pending`. Nothing is sent until you manually call `send()` or run the command.

---

### Send an existing notification

[](#send-an-existing-notification)

```
use Badawy\Pushify\Models\Pushify;

$notification = Pushify::findOrFail($id);
$notification = $push->send($notification);
```

---

### Quick test via Tinker

[](#quick-test-via-tinker)

```
php artisan tinker
```

```
app(\Badawy\Pushify\Contracts\PushifyServiceInterface::class)
    ->sendToAll(
        title: 'Hello',
        body: 'Test from Tinker',
        data: ['type' => 'test'],
        image: null,
        scheduledAt: null,
    );
```

---

### Available interface methods

[](#available-interface-methods)

```
// Store a notification record without sending
public function create(array $payload): Pushify;

// Create and send (or schedule) in one call
public function sendToAll(
    string $title,
    string $body,
    array $data = [],
    ?string $image = null,
    ?string $scheduledAt = null
): Pushify;

// Send an existing stored notification
public function send(Pushify $notification): Pushify;

// Mark due OneSignal scheduled notifications as sent locally
public function markScheduledAsSent(): int;
```

---

Notification Statuses
---------------------

[](#notification-statuses)

StatusMeaning`pending`Stored, not sent yet`processing`Currently being dispatched to the provider`scheduled`Submitted to OneSignal with a future `send_after``sent`Successfully delivered to the provider`failed`Failed — see `error_message` column in the database---

Scheduled Command
-----------------

[](#scheduled-command)

```
php artisan pushify:send-scheduled
```

ProviderWhat it does🔥 FirebaseSends all `pending` notifications where `scheduled_at everyMinute();
```

Or via cron:

```
* * * * * php /path/to/project/artisan pushify:send-scheduled >> /dev/null 2>&1
```

---

Customizing the HTTP Layer
--------------------------

[](#customizing-the-http-layer)

After publishing with `--tag=pushify-http`, you can freely edit:

FilePurpose`app/Http/Controllers/Pushify/PushifyController.php`Request handling &amp; response`app/Http/Requests/Pushify/StorePushifyRequest.php`Validation rules &amp; authorization`app/Http/Resources/Pushify/PushifyResource.php`JSON output shapeThe published controller injects `PushifyServiceInterface` — extend or replace any logic without touching the package internals.

---

Adding a Custom Provider
------------------------

[](#adding-a-custom-provider)

**Step 1 — Create your provider class:**

```
namespace App\Pushify\Providers;

use Badawy\Pushify\Contracts\PushifyProviderInterface;

class CustomProvider implements PushifyProviderInterface
{
    public function sendToAll(
        string $title,
        string $body,
        array $data = [],
        ?string $image = null,
        ?string $scheduledAt = null
    ): array {
        // Your HTTP call or SDK integration here
        return ['success' => true];
    }
}
```

**Step 2 — Register it in `config/pushify.php`:**

```
'providers' => [
    'firebase'  => \Badawy\Pushify\Providers\FirebaseProvider::class,
    'onesignal' => \Badawy\Pushify\Providers\OneSignalProvider::class,
    'custom'    => \App\Pushify\Providers\CustomProvider::class,
],
```

**Step 3 — Activate it in `.env`:**

```
PUSHIFY_PROVIDER=custom
```

---

Store Endpoint Payload
----------------------

[](#store-endpoint-payload)

`POST /pushify`

```
{
    "title": "New offer",
    "body": "Check our latest offers",
    "image": "https://example.com/image.jpg",
    "data": {
        "type": "offer",
        "offer_id": 15
    },
    "scheduled_at": null
}
```

Scheduled example:

```
{
    "title": "Scheduled offer",
    "body": "This will be sent later",
    "image": null,
    "data": { "type": "offer" },
    "scheduled_at": "2026-06-01 09:00:00"
}
```

---

Response Structure
------------------

[](#response-structure)

All endpoints return a consistent JSON envelope:

```
{
    "data": {
        "id": 1,
        "title": "New offer",
        "body": "Check our latest offers",
        "image": "https://example.com/image.jpg",
        "data": { "type": "offer", "offer_id": "15" },
        "scheduled_at": null,
        "status": "sent",
        "sent_at": "2026-01-01T12:00:00+00:00",
        "failed_at": null,
        "created_at": "2026-01-01T11:59:00+00:00",
        "updated_at": "2026-01-01T12:00:00+00:00"
    }
}
```

---

Authors
-------

[](#authors)

[Badawy](https://github.com/Badawy24) · [Hassan](https://github.com/hassanmostfa)

---

License
-------

[](#license)

MIT

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance91

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

43d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/fddc81757758b64bd412fc6edc4dbe9f71079182e3e222ddb6b3c39e9a18848f?d=identicon)[badawy24](/maintainers/badawy24)

---

Top Contributors

[![Badawy24](https://avatars.githubusercontent.com/u/88353210?v=4)](https://github.com/Badawy24 "Badawy24 (2 commits)")[![hassanmostfa](https://avatars.githubusercontent.com/u/113209768?v=4)](https://github.com/hassanmostfa "hassanmostfa (2 commits)")

---

Tags

laravelnotificationsfirebaseFCMpush notificationonesignalpush notifications

### Embed Badge

![Health badge](/badges/badawy24-pushify/health.svg)

```
[![Health](https://phpackages.com/badges/badawy24-pushify/health.svg)](https://phpackages.com/packages/badawy24-pushify)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k14.1M120](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
