You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web:如何从index文件取数并将Firebase通知数据传入Dart状态类?

Flutter Web 两个问题的解决方案:从index取数据、Firebase通知数据传入Stateful类

一、从index.html获取数据到任意Dart文件

方法1:通过全局window变量传递

在index.html的<script>标签中定义全局数据:

<script>
  // 定义全局数据对象
  window.appGlobalData = {
    apiBaseUrl: 'https://your-api-domain.com',
    appEnv: 'production',
    userId: 'user_12345'
  };
</script>

在Dart文件中通过js包读取全局变量:

import 'package:js/js.dart';

// 绑定window上的全局数据
@JS('window.appGlobalData')
external dynamic get appGlobalData;

// 使用示例
void loadAppConfig() {
  print('API地址: ${appGlobalData.apiBaseUrl}');
  print('当前环境: ${appGlobalData.appEnv}');
}

方法2:通过自定义JS函数暴露数据

在index.html中编写返回数据的函数:

<script>
  function getAppInitialData() {
    return {
      theme: 'dark',
      language: 'zh-CN'
    };
  }
</script>

在Dart中调用该函数获取数据:

import 'package:js/js.dart';

@JS('getAppInitialData')
external dynamic getAppInitialData();

void fetchInitialData() {
  var data = getAppInitialData();
  print('主题: ${data.theme}');
  print('语言: ${data.language}');
}

二、获取Firebase通知数据并传入Stateful类

步骤1:在index.html中配置Firebase Messaging并监听通知

确保已引入Firebase SDK,添加消息监听逻辑:

<script>
  // 替换为你的Firebase配置
  const firebaseConfig = {
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_AUTH_DOMAIN",
    projectId: "YOUR_PROJECT_ID",
    storageBucket: "YOUR_STORAGE_BUCKET",
    messagingSenderId: "YOUR_SENDER_ID",
    appId: "YOUR_APP_ID"
  };
  firebase.initializeApp(firebaseConfig);

  const messaging = firebase.messaging();
  // 监听前台收到的通知
  messaging.onMessage((payload) => {
    // 将通知数据存入全局变量
    window.currentNotification = payload;
    // 触发自定义事件通知Dart端
    window.dispatchEvent(new CustomEvent('newNotification', { detail: payload }));
  });

  // 获取FCM Token(可选,用于推送订阅)
  messaging.getToken({ vapidKey: 'YOUR_VAPID_KEY' }).then((token) => {
    console.log('FCM Token:', token);
  });
</script>

步骤2:在Stateful类中接收通知数据

方法A:主动读取全局变量(适合初始化时获取)

import 'package:flutter/material.dart';
import 'package:js/js.dart';

@JS('window.currentNotification')
external dynamic get currentNotification;

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

  @override
  State<NotificationPage> createState() => _NotificationPageState();
}

class _NotificationPageState extends State<NotificationPage> {
  dynamic _receivedNotification;

  @override
  void initState() {
    super.initState();
    // 页面初始化时读取已有的通知数据
    _loadNotificationData();
  }

  void _loadNotificationData() {
    setState(() {
      _receivedNotification = currentNotification;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _receivedNotification != null
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('通知标题: ${_receivedNotification.notification.title}'),
                  const SizedBox(height: 10),
                  Text('通知内容: ${_receivedNotification.notification.body}'),
                ],
              )
            : const Text('暂无通知数据'),
      ),
    );
  }
}

方法B:监听JS自定义事件(实时接收通知)

import 'package:flutter/material.dart';
import 'dart:html' as html;

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

  @override
  State<NotificationPage> createState() => _NotificationPageState();
}

class _NotificationPageState extends State<NotificationPage> {
  dynamic _latestNotification;
  late html.EventListener _notificationListener;

  @override
  void initState() {
    super.initState();
    // 注册自定义事件监听
    _notificationListener = (html.Event event) {
      final detail = (event as html.CustomEvent).detail;
      setState(() {
        _latestNotification = detail;
      });
    };
    html.window.addEventListener('newNotification', _notificationListener);
  }

  @override
  void dispose() {
    // 页面销毁时移除监听
    html.window.removeEventListener('newNotification', _notificationListener);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _latestNotification != null
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('新通知标题: ${_latestNotification.notification.title}'),
                  const SizedBox(height: 10),
                  Text('新通知内容: ${_latestNotification.notification.body}'),
                ],
              )
            : const Text('等待新通知...'),
      ),
    );
  }
}

注意事项

  • 确保pubspec.yaml中已添加js: ^0.6.7依赖
  • Firebase Messaging需要配置正确的VAPID密钥,且网站需部署在HTTPS环境(本地开发可使用localhost)
  • 若需处理后台/关闭状态下的通知点击,需在firebase-messaging-sw.js中添加逻辑,再将数据传递至前端页面

内容的提问来源于stack exchange,提问作者Muhammad Umair Saqib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:22:32