fz_hms_push_kit 0.0.2 copy "fz_hms_push_kit: ^0.0.2" to clipboard
fz_hms_push_kit: ^0.0.2 copied to clipboard

PlatformAndroid

A Flutter package for handling Huawei Mobile Services (HMS) Push Kit — token retrieval, foreground/background message handling, notification tap events, and a server-side helper to obtain OAuth2 acces [...]

example/lib/main.dart

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fz_hms_push_kit/fz_hms_push_kit.dart';

// ─────────────────────────────────────────────────────────────────────────────
// Entry point
// ─────────────────────────────────────────────────────────────────────────────

/// Top-level background message handler for HMS Push Kit.
/// Must be a top-level or static function to run in background isolates.
@pragma('vm:entry-point')
void customBackgroundMessageHandler(RemoteMessage message) {
  debugPrint('[Example Background] Message received in background: ${message.data}');
}
final HmsNotificationService hmsService=HmsNotificationServiceImpl();
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await hmsService.initialize(
    onTokenReceived: (String token) {
      debugPrint('[Example] HMS Token: $token');
    },
    onBackgroundMessage: customBackgroundMessageHandler,
  );

  runApp(const HmsPushKitExampleApp());
}

// ─────────────────────────────────────────────────────────────────────────────
// App Configuration
// ─────────────────────────────────────────────────────────────────────────────

class HmsPushKitExampleApp extends StatelessWidget {
  const HmsPushKitExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'HMS Push Kit',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        brightness: Brightness.dark,
        scaffoldBackgroundColor: const Color(0xFF090D16),
        colorScheme: const ColorScheme.dark(
          primary: Color(0xFFE11D48), // Vibrant Huawei Rose
          secondary: Color(0xFFF43F5E),
          surface: Color(0xFF111827),
          onSurface: Color(0xFFF3F4F6),
        ),
        fontFamily: 'Roboto',
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// Home Page
// ─────────────────────────────────────────────────────────────────────────────

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String _token = '';
  final List<Map<String, dynamic>> _messages = [];
  StreamSubscription<String?>? _sub;

  // Form controllers
  final _clientSecretCtrl = TextEditingController();
  final _appIdCtrl = TextEditingController(text: '110577713');
  final _titleCtrl = TextEditingController(text: '⚡ HMS Push Notification');
  final _bodyCtrl = TextEditingController(
      text: 'This is a live test push notification sent via HMS REST API.');

  bool _isSecretVisible = false;
  bool _isSending = false;
  String _sendResult = '';
  bool _sendSuccess = false;
  bool _copiedToken = false;

  @override
  void initState() {
    super.initState();

    _token = hmsService.token;

    // Listen for notification taps & incoming messages
    hmsService.onNotificationClick.listen((msg) {
      if (msg == null) return;
      try {
        final decoded = jsonDecode(msg) as Map<String, dynamic>;
        setState(() {
          _messages.insert(0, {
            ...decoded,
            'time': DateTime.now().toIso8601String().substring(11, 19),
          });
        });
      } catch (_) {
        setState(() {
          _messages.insert(0, {
            'title': 'Raw Message',
            'body': msg,
            'time': DateTime.now().toIso8601String().substring(11, 19),
          });
        });
      }
    });

    _sub = hmsService.onNotificationClick.listen((_) {
      final t = hmsService.token;
      if (t.isNotEmpty && t != _token) {
        setState(() => _token = t);
      }
    });
  }

  @override
  void dispose() {
    _sub?.cancel();
    _clientSecretCtrl.dispose();
    _appIdCtrl.dispose();
    _titleCtrl.dispose();
    _bodyCtrl.dispose();
    super.dispose();
  }

  void _copyToClipboard(String text) {
    Clipboard.setData(ClipboardData(text: text));
    setState(() => _copiedToken = true);
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: const Row(
          children: [
            Icon(Icons.check_circle_rounded, color: Color(0xFF10B981), size: 18),
            SizedBox(width: 8),
            Text('Token copied to clipboard!'),
          ],
        ),
        backgroundColor: const Color(0xFF1E293B),
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        duration: const Duration(seconds: 2),
      ),
    );
    Future.delayed(const Duration(seconds: 2), () {
      if (mounted) setState(() => _copiedToken = false);
    });
  }

  Future<void> _sendNotification() async {
    if (_token.isEmpty || _token == 'Waiting for token...') {
      setState(() {
        _sendSuccess = false;
        _sendResult = 'Device token is not available yet. Make sure HMS Core is configured.';
      });
      return;
    }

    final secret = _clientSecretCtrl.text.trim();
    if (secret.isEmpty) {
      setState(() {
        _sendSuccess = false;
        _sendResult = 'Please enter your HMS Client Secret from AppGallery Connect.';
      });
      return;
    }

    setState(() {
      _isSending = true;
      _sendResult = '';
    });

    try {
      final appId = _appIdCtrl.text.trim().isEmpty ? '110577713' : _appIdCtrl.text.trim();

      final pushClient = HmsPushClient(
        appId: appId,
        clientSecret: secret,
      );

      final result = await pushClient.sendNotification(
        HmsNotification(
          title: _titleCtrl.text.trim(),
          body: _bodyCtrl.text.trim(),
          tokens: [_token],
          data: const {
            'id': '42',
            'view': 'dashboard',
            'type': 'test_push',
          },
        ),
      );

      setState(() {
        _sendSuccess = result.isSuccess;
        _sendResult = result.isSuccess
            ? 'Notification sent successfully!\nRequest ID: ${result.requestId}'
            : 'Error [${result.code}]: ${result.msg}';
      });
    } catch (e) {
      setState(() {
        _sendSuccess = false;
        _sendResult = 'Exception: $e';
      });
    } finally {
      setState(() => _isSending = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFF0F172A),
              Color(0xFF090D16),
            ],
          ),
        ),
        child: SafeArea(
          child: CustomScrollView(
            physics: const BouncingScrollPhysics(),
            slivers: [
              // ── Modern Header ──────────────────────────────────────────────
              SliverToBoxAdapter(
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(20, 20, 20, 10),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        children: [
                          Container(
                            padding: const EdgeInsets.all(10),
                            decoration: BoxDecoration(
                              gradient: const LinearGradient(
                                colors: [Color(0xFFE11D48), Color(0xFF9F1239)],
                              ),
                              borderRadius: BorderRadius.circular(14),
                              boxShadow: [
                                BoxShadow(
                                  color: const Color(0xFFE11D48).withOpacity(0.35),
                                  blurRadius: 12,
                                  offset: const Offset(0, 4),
                                ),
                              ],
                            ),
                            child: const Icon(
                              Icons.notifications_active_rounded,
                              color: Colors.white,
                              size: 24,
                            ),
                          ),
                          const SizedBox(width: 14),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const Text(
                                'HMS Push Kit',
                                style: TextStyle(
                                  fontSize: 20,
                                  fontWeight: FontWeight.bold,
                                  letterSpacing: 0.3,
                                  color: Colors.white,
                                ),
                              ),
                              const SizedBox(height: 2),
                              Row(
                                children: [
                                  Container(
                                    width: 8,
                                    height: 8,
                                    decoration: BoxDecoration(
                                      color: _token.isNotEmpty ? const Color(0xFF10B981) : const Color(0xFFF59E0B),
                                      shape: BoxShape.circle,
                                    ),
                                  ),
                                  const SizedBox(width: 6),
                                  Text(
                                    _token.isNotEmpty ? 'Service Active' : 'Waiting for Token',
                                    style: const TextStyle(
                                      fontSize: 12,
                                      color: Color(0xFF94A3B8),
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                      Container(
                        padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                        decoration: BoxDecoration(
                          color: const Color(0xFF1E293B),
                          borderRadius: BorderRadius.circular(20),
                          border: Border.all(color: const Color(0xFF334155)),
                        ),
                        child: const Text(
                          'v0.0.1',
                          style: TextStyle(
                            fontSize: 12,
                            fontWeight: FontWeight.w600,
                            color: Color(0xFFF43F5E),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),

              SliverPadding(
                padding: const EdgeInsets.all(20),
                sliver: SliverList(
                  delegate: SliverChildListDelegate([
                    // ── Device Token Card ────────────────────────────────────
                    _GlassCard(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              const Row(
                                children: [
                                  Icon(Icons.vpn_key_rounded,
                                      color: Color(0xFFF43F5E), size: 18),
                                  SizedBox(width: 8),
                                  Text(
                                    'HMS Device Push Token',
                                    style: TextStyle(
                                      fontSize: 15,
                                      fontWeight: FontWeight.w700,
                                      color: Colors.white,
                                    ),
                                  ),
                                ],
                              ),
                              if (_token.isNotEmpty)
                                Material(
                                  color: Colors.transparent,
                                  child: InkWell(
                                    onTap: () => _copyToClipboard(_token),
                                    borderRadius: BorderRadius.circular(8),
                                    child: Padding(
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 8, vertical: 4),
                                      child: Row(
                                        children: [
                                          Icon(
                                            _copiedToken
                                                ? Icons.check_rounded
                                                : Icons.copy_rounded,
                                            size: 14,
                                            color: _copiedToken
                                                ? const Color(0xFF10B981)
                                                : const Color(0xFF94A3B8),
                                          ),
                                          const SizedBox(width: 4),
                                          Text(
                                            _copiedToken ? 'Copied' : 'Copy',
                                            style: TextStyle(
                                              fontSize: 12,
                                              color: _copiedToken
                                                  ? const Color(0xFF10B981)
                                                  : const Color(0xFF94A3B8),
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ),
                                ),
                            ],
                          ),
                          const SizedBox(height: 12),
                          Container(
                            width: double.infinity,
                            padding: const EdgeInsets.all(12),
                            decoration: BoxDecoration(
                              color: const Color(0xFF0F172A),
                              borderRadius: BorderRadius.circular(10),
                              border: Border.all(color: const Color(0xFF1E293B)),
                            ),
                            child: SelectableText(
                              _token.isEmpty
                                  ? 'Fetching device token from Huawei Push Kit...'
                                  : _token,
                              style: TextStyle(
                                fontFamily: 'monospace',
                                fontSize: 12,
                                height: 1.4,
                                color: _token.isEmpty
                                    ? const Color(0xFF64748B)
                                    : const Color(0xFF38BDF8),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    const SizedBox(height: 20),

                    // ── Send Test Push Section ──────────────────────────────
                    _GlassCard(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Row(
                            children: [
                              Icon(Icons.send_rounded,
                                  color: Color(0xFFF43F5E), size: 18),
                              SizedBox(width: 8),
                              Text(
                                'Send Push Notification',
                                style: TextStyle(
                                  fontSize: 15,
                                  fontWeight: FontWeight.w700,
                                  color: Colors.white,
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 4),
                          const Text(
                            'Test sending a push notification via Huawei Push REST API',
                            style: TextStyle(fontSize: 12, color: Color(0xFF64748B)),
                          ),
                          const SizedBox(height: 16),

                          // App ID & Secret Input
                          Row(
                            children: [
                              Expanded(
                                flex: 2,
                                child: _StyledTextField(
                                  controller: _appIdCtrl,
                                  label: 'HMS App ID',
                                  prefixIcon: Icons.apps_rounded,
                                ),
                              ),
                              const SizedBox(width: 12),
                              Expanded(
                                flex: 3,
                                child: _StyledTextField(
                                  controller: _clientSecretCtrl,
                                  label: 'Client Secret',
                                  obscureText: !_isSecretVisible,
                                  prefixIcon: Icons.lock_outline_rounded,
                                  suffixIcon: IconButton(
                                    icon: Icon(
                                      _isSecretVisible
                                          ? Icons.visibility_off_rounded
                                          : Icons.visibility_rounded,
                                      size: 18,
                                      color: const Color(0xFF64748B),
                                    ),
                                    onPressed: () {
                                      setState(() =>
                                          _isSecretVisible = !_isSecretVisible);
                                    },
                                  ),
                                ),
                              ),
                            ],
                          ),

                          const SizedBox(height: 12),
                          _StyledTextField(
                            controller: _titleCtrl,
                            label: 'Notification Title',
                            prefixIcon: Icons.title_rounded,
                          ),

                          const SizedBox(height: 12),
                          _StyledTextField(
                            controller: _bodyCtrl,
                            label: 'Notification Body',
                            maxLines: 2,
                            prefixIcon: Icons.notes_rounded,
                          ),

                          const SizedBox(height: 16),

                          // Action Button
                          SizedBox(
                            width: double.infinity,
                            height: 48,
                            child: DecoratedBox(
                              decoration: BoxDecoration(
                                gradient: const LinearGradient(
                                  colors: [
                                    Color(0xFFE11D48),
                                    Color(0xFFBE123C),
                                  ],
                                ),
                                borderRadius: BorderRadius.circular(12),
                                boxShadow: [
                                  BoxShadow(
                                    color: const Color(0xFFE11D48).withOpacity(0.3),
                                    blurRadius: 10,
                                    offset: const Offset(0, 4),
                                  ),
                                ],
                              ),
                              child: ElevatedButton(
                                onPressed: _isSending ? null : _sendNotification,
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.transparent,
                                  shadowColor: Colors.transparent,
                                  shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(12),
                                  ),
                                ),
                                child: _isSending
                                    ? const SizedBox(
                                        width: 20,
                                        height: 20,
                                        child: CircularProgressIndicator(
                                          strokeWidth: 2.5,
                                          valueColor:
                                              AlwaysStoppedAnimation<Color>(
                                                  Colors.white),
                                        ),
                                      )
                                    : const Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.center,
                                        children: [
                                          Icon(Icons.send_rounded,
                                              size: 18, color: Colors.white),
                                          SizedBox(width: 8),
                                          Text(
                                            'Send Notification',
                                            style: TextStyle(
                                              fontSize: 14,
                                              fontWeight: FontWeight.bold,
                                              color: Colors.white,
                                            ),
                                          ),
                                        ],
                                      ),
                              ),
                            ),
                          ),

                          // Response banner
                          if (_sendResult.isNotEmpty) ...[
                            const SizedBox(height: 14),
                            AnimatedContainer(
                              duration: const Duration(milliseconds: 300),
                              padding: const EdgeInsets.all(12),
                              decoration: BoxDecoration(
                                color: _sendSuccess
                                    ? const Color(0xFF064E3B).withOpacity(0.4)
                                    : const Color(0xFF7F1D1D).withOpacity(0.4),
                                borderRadius: BorderRadius.circular(10),
                                border: Border.all(
                                  color: _sendSuccess
                                      ? const Color(0xFF059669)
                                      : const Color(0xFFDC2626),
                                ),
                              ),
                              child: Row(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Icon(
                                    _sendSuccess
                                        ? Icons.check_circle_outline_rounded
                                        : Icons.error_outline_rounded,
                                    color: _sendSuccess
                                        ? const Color(0xFF34D399)
                                        : const Color(0xFFFCA5A5),
                                    size: 20,
                                  ),
                                  const SizedBox(width: 10),
                                  Expanded(
                                    child: SelectableText(
                                      _sendResult,
                                      style: TextStyle(
                                        fontSize: 12,
                                        height: 1.4,
                                        color: _sendSuccess
                                            ? const Color(0xFFD1FAE5)
                                            : const Color(0xFFFEE2E2),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ],
                      ),
                    ),

                    const SizedBox(height: 20),

                    // ── Received Messages Feed ──────────────────────────────
                    _GlassCard(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              const Row(
                                children: [
                                  Icon(Icons.inbox_rounded,
                                      color: Color(0xFFF43F5E), size: 18),
                                  SizedBox(width: 8),
                                  Text(
                                    'Received Messages',
                                    style: TextStyle(
                                      fontSize: 15,
                                      fontWeight: FontWeight.w700,
                                      color: Colors.white,
                                    ),
                                  ),
                                ],
                              ),
                              Container(
                                padding: const EdgeInsets.symmetric(
                                    horizontal: 8, vertical: 2),
                                decoration: BoxDecoration(
                                  color: const Color(0xFF1E293B),
                                  borderRadius: BorderRadius.circular(12),
                                ),
                                child: Text(
                                  '${_messages.length}',
                                  style: const TextStyle(
                                    fontSize: 12,
                                    fontWeight: FontWeight.bold,
                                    color: Color(0xFFF43F5E),
                                  ),
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 12),
                          if (_messages.isEmpty)
                            Container(
                              width: double.infinity,
                              padding: const EdgeInsets.symmetric(vertical: 30),
                              decoration: BoxDecoration(
                                color: const Color(0xFF0F172A).withOpacity(0.5),
                                borderRadius: BorderRadius.circular(10),
                                border: Border.all(
                                    color: const Color(0xFF1E293B)),
                              ),
                              child: const Column(
                                children: [
                                  Icon(Icons.notifications_none_rounded,
                                      size: 40, color: Color(0xFF475569)),
                                  SizedBox(height: 8),
                                  Text(
                                    'No notifications received yet',
                                    style: TextStyle(
                                        fontSize: 13,
                                        color: Color(0xFF64748B)),
                                  ),
                                  SizedBox(height: 4),
                                  Text(
                                    'Tap a notification or send a test payload above',
                                    style: TextStyle(
                                        fontSize: 11,
                                        color: Color(0xFF475569)),
                                  ),
                                ],
                              ),
                            )
                          else
                            ListView.separated(
                              shrinkWrap: true,
                              physics: const NeverScrollableScrollPhysics(),
                              itemCount: _messages.length,
                              separatorBuilder: (_, __) =>
                                  const SizedBox(height: 10),
                              itemBuilder: (context, index) {
                                final msg = _messages[index];
                                return Container(
                                  padding: const EdgeInsets.all(12),
                                  decoration: BoxDecoration(
                                    color: const Color(0xFF0F172A),
                                    borderRadius: BorderRadius.circular(10),
                                    border: Border.all(
                                        color: const Color(0xFF1E293B)),
                                  ),
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.spaceBetween,
                                        children: [
                                          Text(
                                            msg['title']?.toString() ??
                                                'Notification Payload',
                                            style: const TextStyle(
                                              fontWeight: FontWeight.bold,
                                              fontSize: 13,
                                              color: Colors.white,
                                            ),
                                          ),
                                          Text(
                                            msg['time']?.toString() ?? '',
                                            style: const TextStyle(
                                              fontSize: 11,
                                              color: Color(0xFF64748B),
                                            ),
                                          ),
                                        ],
                                      ),
                                      const SizedBox(height: 6),
                                      Wrap(
                                        spacing: 6,
                                        runSpacing: 6,
                                        children: msg.entries
                                            .where((e) =>
                                                e.key != 'title' &&
                                                e.key != 'time')
                                            .map((e) => Container(
                                                  padding: const EdgeInsets
                                                      .symmetric(
                                                      horizontal: 8,
                                                      vertical: 3),
                                                  decoration: BoxDecoration(
                                                    color:
                                                        const Color(0xFF1E293B),
                                                    borderRadius:
                                                        BorderRadius.circular(6),
                                                  ),
                                                  child: Text(
                                                    '${e.key}: ${e.value}',
                                                    style: const TextStyle(
                                                      fontSize: 11,
                                                      fontFamily: 'monospace',
                                                      color: Color(0xFF38BDF8),
                                                    ),
                                                  ),
                                                ))
                                            .toList(),
                                      ),
                                    ],
                                  ),
                                );
                              },
                            ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 30),
                  ]),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// Reusable UI Components
// ─────────────────────────────────────────────────────────────────────────────

class _GlassCard extends StatelessWidget {
  const _GlassCard({required this.child});

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: const Color(0xFF111827).withOpacity(0.85),
        borderRadius: BorderRadius.circular(18),
        border: Border.all(color: const Color(0xFF1F2937)),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.2),
            blurRadius: 16,
            offset: const Offset(0, 6),
          ),
        ],
      ),
      child: child,
    );
  }
}

class _StyledTextField extends StatelessWidget {
  const _StyledTextField({
    required this.controller,
    required this.label,
    this.obscureText = false,
    this.maxLines = 1,
    this.prefixIcon,
    this.suffixIcon,
  });

  final TextEditingController controller;
  final String label;
  final bool obscureText;
  final int maxLines;
  final IconData? prefixIcon;
  final Widget? suffixIcon;

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: controller,
      obscureText: obscureText,
      maxLines: maxLines,
      style: const TextStyle(fontSize: 13, color: Colors.white),
      decoration: InputDecoration(
        labelText: label,
        labelStyle: const TextStyle(fontSize: 12, color: Color(0xFF64748B)),
        floatingLabelStyle: const TextStyle(color: Color(0xFFF43F5E)),
        isDense: true,
        filled: true,
        fillColor: const Color(0xFF0F172A),
        prefixIcon: prefixIcon != null
            ? Icon(prefixIcon, size: 18, color: const Color(0xFF64748B))
            : null,
        suffixIcon: suffixIcon,
        contentPadding:
            const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Color(0xFF1E293B)),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Color(0xFFE11D48)),
        ),
      ),
    );
  }
}
3
likes
130
points
68
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter package for handling Huawei Mobile Services (HMS) Push Kit — token retrieval, foreground/background message handling, notification tap events, and a server-side helper to obtain OAuth2 access tokens and send push notifications via the Huawei Push REST API.

Repository (GitHub)
View/report issues

Topics

#push-notifications #huawei #hms #notifications #push-kit

Funding

Consider supporting this project:

buymeacoffee.com

License

MIT (license)

Dependencies

flutter, http, huawei_push, rxdart

More

Packages that depend on fz_hms_push_kit