Skip to content

Commit 28270f9

Browse files
livewire component is changed to only alpine and api routes added
1 parent a627074 commit 28270f9

File tree

7 files changed

+280
-94
lines changed

7 files changed

+280
-94
lines changed

src/Channels/FcmChannel.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ class FcmChannel
1818

1919
public function __construct()
2020
{
21-
$this->firebase_credentials_path = (config('fmc.firebase_credentials') && trim(config('fmc.firebase_credentials')) == 'auto' ? 'app/firebase-auth.js' : null) ? storage_path(config('fmc.firebase_credentials')) : null;
21+
$this->firebase_credentials_path = config('fcm.firebase_credentials') && trim(config('fcm.firebase_credentials')) == 'auto' ? 'app/firebase-auth.js' : config('fcm.firebase_credentials');
22+
23+
$this->firebase_credentials_path = storage_path($this->firebase_credentials_path);
2224

2325
// dd($this->firebase_credentials_path);
2426

@@ -60,7 +62,7 @@ public function send(object $notifiable, Notification $notification)
6062

6163
if (isset($data->apns) && is_array($data->apns)) {
6264

63-
$message = $message->withApnsConfig(ApnsConfig::fromArray($data->apns()));
65+
$message = $message->withApnsConfig(ApnsConfig::fromArray($data->apns));
6466
}
6567

6668
$report = $messaging->sendMulticast($message, $deviceTokens);
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
namespace JoydeepBhowmik\LaravelPushNotification\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
use App\Http\Controllers\Controller;
7+
use JoydeepBhowmik\LaravelPushNotification\Models\UserDevice;
8+
9+
class NotificationController extends Controller
10+
{
11+
12+
function checkIfNotificationStatus(Request $request)
13+
{
14+
15+
try {
16+
// Validate the request
17+
$request->validate([
18+
'token' => 'required'
19+
]);
20+
21+
$token = $request->token;
22+
23+
// Check if the device exists
24+
$device = UserDevice::where('token', $token)->first();
25+
26+
// Response if the device exists and notificable is true
27+
return response()->json([
28+
'allowed' => $device && $device->notificable,
29+
'message' => $device ? 'Device found' : 'Device not found',
30+
], $device ? 200 : 404);
31+
} catch (\Exception $e) {
32+
return response()->json([
33+
'success' => false,
34+
'message' => 'An error occurred: ' . $e->getMessage(),
35+
], 500);
36+
}
37+
}
38+
39+
function enableNotification(Request $request)
40+
{
41+
42+
try {
43+
// Validate the request
44+
$request->validate([
45+
'token' => 'required',
46+
'os' => 'required'
47+
]);
48+
49+
$token = $request->token;
50+
$os = $request->os;
51+
52+
// Check if the device already exists
53+
$device = UserDevice::where('token', $token)->first();
54+
55+
if (!$device) {
56+
// Create new device if not exists
57+
$device = new UserDevice();
58+
$device->token = $token;
59+
}
60+
61+
$device->device = $os;
62+
$device->user_id = $request->user()?->id; // Assign user_id if logged in
63+
$device->notificable = true;
64+
65+
// Save the device
66+
$status = $device->save();
67+
68+
return response()->json([
69+
'success' => $status,
70+
'message' => $status ? 'Notifications enabled successfully' : 'Failed to enable notifications'
71+
], $status ? 200 : 500);
72+
} catch (\Exception $e) {
73+
return response()->json([
74+
'success' => false,
75+
'message' => 'An error occurred: ' . $e->getMessage(),
76+
], 500);
77+
}
78+
}
79+
80+
function disableNotification(Request $request)
81+
{
82+
83+
try {
84+
// Validate the request
85+
$request->validate([
86+
'token' => 'required',
87+
]);
88+
89+
$token = $request->token;
90+
91+
// Find the device with the token
92+
$device = UserDevice::where('token', $token)->first();
93+
94+
if ($device) {
95+
// Disable notifications for the device
96+
$device->notificable = false;
97+
$status = $device->save();
98+
99+
return response()->json([
100+
'success' => $status,
101+
'message' => $status ? 'Notifications disabled successfully' : 'Failed to disable notifications'
102+
], $status ? 200 : 500);
103+
} else {
104+
return response()->json([
105+
'success' => false,
106+
'message' => 'Device not found'
107+
], 404);
108+
}
109+
} catch (\Exception $e) {
110+
return response()->json([
111+
'success' => false,
112+
'message' => 'An error occurred: ' . $e->getMessage(),
113+
], 500);
114+
}
115+
}
116+
}

src/Providers/FcmServiceProvider.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@
33
namespace JoydeepBhowmik\LaravelPushNotification\Providers;
44

55
use Illuminate\Support\ServiceProvider;
6+
use Illuminate\Support\Facades\Route;
67

78
class FcmServiceProvider extends ServiceProvider
89
{
910
public function boot()
1011
{
12+
13+
Route::middleware('api')->prefix('api')->group(function () {
14+
$this->loadRoutesFrom(__DIR__ . '/../routes/api.php');
15+
});
16+
17+
Route::middleware('web')->prefix('fcm')->group(function () {
18+
$this->loadRoutesFrom(__DIR__ . '/../routes/web.php');
19+
});
20+
1121
// Load migrations
12-
$this->loadMigrationsFrom(__DIR__ . '/migrations');
22+
$this->loadMigrationsFrom(__DIR__ . '/../migrations');
1323

1424
// Publish all resources under one tag
1525
$this->publishes([

src/resources/js/fcm.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ const firebaseConfig = {
2727
messagingSenderId: "YOUR_MESSAGING_SENDER_ID_HERE",
2828
appId: "YOUR_APP_ID_HERE",
2929
measurementId: "YOUR_MEASUREMENT_ID_HERE",
30+
apiKey: "YOUR_API_KEY_HERE",
31+
authDomain: "YOUR_AUTH_DOMAIN_HERE",
32+
projectId: "YOUR_PROJECT_ID_HERE",
33+
storageBucket: "YOUR_STORAGE_BUCKET_HERE",
34+
messagingSenderId: "YOUR_MESSAGING_SENDER_ID_HERE",
35+
appId: "YOUR_APP_ID_HERE",
36+
measurementId: "YOUR_MEASUREMENT_ID_HERE",
3037
};
3138

3239
// Initialize Firebase
Lines changed: 122 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,124 @@
1-
<?php
2-
use App\Models\UserDevice;
3-
use function Livewire\Volt\{state, on, mount};
4-
5-
state(['push_notification' => false]);
6-
7-
$checkIfNotificationOn = function (string $token = null) {
8-
$device = UserDevice::where('token', $token)->first();
9-
10-
if (!$device) {
11-
return;
12-
}
13-
14-
if ($device && $device->notificable) {
15-
return $this->dispatch('notification-status-updated', allowed: true);
16-
}
17-
};
18-
19-
$turnOnNotification = function (string $token, string $os) {
20-
$device = UserDevice::where('token', $token)->first();
21-
22-
if (!$device) {
23-
$device = new UserDevice();
24-
$device->token = $token;
25-
}
26-
27-
$device->device = $os;
28-
29-
$device->user_id = auth()->user()?->id;
30-
31-
$device->notificable = true;
32-
33-
$device->save() && $this->dispatch('notification-status-updated', allowed: true);
34-
};
35-
36-
$turnOffNotification = function (string $token) {
37-
$device = UserDevice::where('token', $token)->first();
38-
39-
$device->notificable = false;
40-
41-
$device->save() && $this->dispatch('notification-status-updated', allowed: false);
42-
};
43-
44-
?>
45-
46-
<div {{ $attributes }}>
47-
@volt('push-notification-switch-volt')
48-
<div wire:loading.class='disabled' x-data="{
49-
push_notification: Notification.permission === 'granted' && $wire.push_notification,
50-
token: null,
51-
os: null,
52-
init() {
53-
54-
if (Notification.permission === 'granted') {
55-
56-
$store.fcm.getPermission((data) => {
57-
const { os, token } = data;
58-
this.token = token;
59-
this.os = os;
60-
$wire.checkIfNotificationOn(token);
61-
});
62-
}
63-
$watch('push_notification', (value) => {
64-
if (value) {
65-
if (Notification.permission !== 'granted') {
66-
$store.fcm.getPermission((data) => {});
67-
}
68-
return $wire.turnOnNotification(this.token, this.os)
69-
};
70-
return $wire.turnOffNotification(this.token);
1+
@props(['label' => 'allowed Notification', 'id' => 'toggle' . uniqid()])
2+
<label
3+
{{ $attributes->merge([
4+
'class' => 'relative inline-flex cursor-pointer items-center',
5+
'for' => $id,
6+
]) }}
7+
x-data="{
8+
push_notification: $persist(false),
9+
token: null,
10+
isLoading: false,
11+
init() {
12+
this.checkNotificationStatus();
13+
14+
},
15+
async toggleNotification($el) {
16+
17+
console.log($el.checked);
18+
19+
if ($el.checked) {
20+
return await this.enableNotification();
21+
} else {
22+
return await this.disableNotification();
23+
}
24+
},
25+
async checkNotificationStatus() {
26+
27+
if (this.push_notification) return;
28+
29+
if (Notification.permission === 'granted') {
30+
$store.fcm.getPermission(async (data) => {
31+
const { token } = data;
32+
this.token = token;
33+
try {
34+
this.isLoading = true;
35+
const response = await fetch('{{ route('fcm-notification.check') }}', {
36+
method: 'POST',
37+
headers: {
38+
'Content-Type': 'application/json',
39+
'X-CSRF-TOKEN': '{{ csrf_token() }}',
40+
},
41+
body: JSON.stringify({ token: this.token }),
42+
});
43+
const data = await response.json();
44+
console.log(data)
45+
this.push_notification = data.allowed;
46+
} catch (error) {
47+
console.error('Error checking notification status', error);
48+
} finally {
49+
this.isLoading = false;
50+
}
51+
})
52+
}
53+
},
54+
55+
async enableNotification() {
56+
57+
const permission = await Notification.requestPermission();
58+
if (permission === 'granted') {
59+
$store.fcm.getPermission(async (data) => {
60+
const { os, token } = data;
61+
this.token = token;
62+
this.os = os;
63+
try {
64+
this.isLoading = true;
65+
const response = await fetch('{{ route('fcm-notification.enable') }}', {
66+
method: 'POST',
67+
headers: {
68+
'Content-Type': 'application/json',
69+
'X-CSRF-TOKEN': '{{ csrf_token() }}',
70+
},
71+
body: JSON.stringify({ token: this.token, os: this.os }),
72+
});
73+
const data = await response.json();
74+
console.log(data)
75+
this.push_notification = data.success ? true : false;
76+
} catch (error) {
77+
console.error('Error enabling notification', error);
78+
} finally {
79+
this.isLoading = false;
80+
}
81+
});
82+
83+
}
84+
},
85+
86+
async disableNotification() {
87+
88+
const permission = await Notification.requestPermission();
89+
if (permission === 'granted') {
90+
$store.fcm.getPermission(async (data) => {
91+
const { os, token } = data;
92+
this.token = token;
93+
this.os = os;
94+
try {
95+
this.isLoading = true;
96+
const response = await fetch('{{ route('fcm-notification.disable') }}', {
97+
method: 'POST',
98+
headers: {
99+
'Content-Type': 'application/json',
100+
'X-CSRF-TOKEN': '{{ csrf_token() }}',
101+
},
102+
body: JSON.stringify({ token: this.token }),
103+
});
104+
const data = await response.json();
105+
console.log(data)
106+
this.push_notification = data.success ? false : true;
107+
} catch (error) {
108+
console.error('Error disabling notification', error);
109+
} finally {
110+
this.isLoading = false;
111+
}
71112
});
72-
},
73-
74-
resetStatus(e) {
75-
const { allowed } = e.detail;
76-
this.push_notification = allowed;
113+
77114
}
78-
79-
}" wire:loading.class='disabled'
80-
@notification-status-updated="resetStatus">
81-
82-
<label class="inline-flex cursor-pointer items-center">
83-
<input class="peer sr-only" type="checkbox" x-model='push_notification'>
84-
<div
85-
class="peer relative h-6 w-11 rounded-full bg-gray-200 after:absolute after:start-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-600 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rtl:peer-checked:after:-translate-x-full dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-blue-800">
86-
</div>
87-
<span class="ms-3 text-sm font-medium text-gray-900 dark:text-gray-300">Allow Push Notification</span>
88-
</label>
89-
90-
</div>
91-
@endvolt
92-
93-
</div>
115+
},
116+
}">
117+
,
118+
<input class="peer sr-only" id="{{ $id }}" type="checkbox" @change='toggleNotification($el)'
119+
x-model='push_notification'>
120+
<div
121+
class="peer h-6 w-11 rounded-full bg-gray-300 after:absolute after:left-[2px] after:top-0.5 after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-600 peer-checked:after:translate-x-5 peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">
122+
</div>
123+
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">{{ $label }}</span>
124+
</label>

0 commit comments

Comments
 (0)