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

基于Flutter与ASP.NET Core的Firebase Cloud Messaging配置求助

糕点店订单系统 Firebase + ASP.NET Core + Flutter 完整配置方案

一、Firebase 基础配置

  • 登录Firebase控制台,创建新项目(命名如「糕点店订单系统」),按需禁用Google Analytics,完成项目创建。
  • 添加两类应用:
    • Web应用:用于ASP.NET Core后端集成,复制生成的firebaseConfig配置内容备用。
    • Android/iOS应用:用于Flutter端,分别下载google-services.json(Android)和GoogleService-Info.plist(iOS),保存到对应项目目录。
  • 启用Firebase Cloud Messaging(FCM):在控制台左侧菜单进入「Cloud Messaging」,完成基础配置(如设置通知图标)。
  • 生成Admin SDK密钥:进入「项目设置」→「服务账户」,点击「生成新的私钥」,下载JSON密钥文件,保存到ASP.NET Core项目的安全目录。

二、ASP.NET Core 后端配置(订单提交触发FCM通知)

  1. 安装依赖包
    在项目中执行以下NuGet命令:
Install-Package FirebaseAdmin
Install-Package Microsoft.EntityFrameworkCore.SqlServer
  1. 初始化Firebase Admin SDK
    在Program.cs中添加初始化代码:
var firebaseOptions = new FirebaseAdmin.AppOptions
{
    Credential = FirebaseAdmin.Auth.FirebaseCredential.FromFile("你的密钥文件路径.json")
};
FirebaseAdmin.FirebaseApp.Create(firebaseOptions);
  1. 配置SQL Server与订单实体
    创建订单实体类:
public class Order
{
    public int Id { get; set; }
    public string CustomerName { get; set; }
    public string TelephoneNumber { get; set; }
    public string PastryName { get; set; }
    public int Quantity { get; set; }
    public string Address { get; set; }
    public DateTime CreateTime { get; set; } = DateTime.Now;
}

创建数据库上下文:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
    public DbSet<Order> Orders { get; set; }
}

在Program.cs中配置SQL Server连接:

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

在appsettings.json中添加连接字符串:

"ConnectionStrings": {
    "DefaultConnection": "Server=你的服务器地址;Database=PastryShopDB;Trusted_Connection=True;TrustServerCertificate=True;"
}
  1. 编写订单接口与FCM通知逻辑
    创建API控制器:
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    private readonly AppDbContext _dbContext;
    private readonly FirebaseAdmin.Messaging.FirebaseMessaging _fcmMessaging;

    public OrdersController(AppDbContext dbContext)
    {
        _dbContext = dbContext;
        _fcmMessaging = FirebaseAdmin.Messaging.FirebaseMessaging.DefaultInstance;
    }

    [HttpPost]
    public async Task<IActionResult> SubmitOrder(Order order)
    {
        if (!ModelState.IsValid)
            return BadRequest(ModelState);
        
        // 保存订单到SQL Server
        _dbContext.Orders.Add(order);
        await _dbContext.SaveChangesAsync();

        // 构建FCM通知内容
        var notificationMessage = new FirebaseAdmin.Messaging.Message()
        {
            Notification = new FirebaseAdmin.Messaging.Notification()
            {
                Title = "新订单提醒",
                Body = $"客户:{order.CustomerName}\n手机号:{order.TelephoneNumber}\n糕点:{order.PastryName}\n数量:{order.Quantity}\n地址:{order.Address}"
            },
            // 替换为店主设备的FCM令牌(需提前从Flutter端获取并存储)
            Token = "店主的FCM_TOKEN"
        };

        // 发送通知
        try
        {
            await _fcmMessaging.SendAsync(notificationMessage);
        }
        catch (Exception ex)
        {
            // 记录发送失败日志
            Console.WriteLine($"FCM通知发送失败:{ex.Message}");
        }

        return Ok(new { OrderId = order.Id, Message = "订单提交成功" });
    }
}

额外新增店主令牌存储接口:

[ApiController]
[Route("api/owner")]
public class OwnerController : ControllerBase
{
    // 可将令牌存储到数据库或配置文件,示例仅做演示
    private static string _shopOwnerToken;

    [HttpPost("token")]
    public IActionResult SaveToken([FromBody] TokenRequest request)
    {
        _shopOwnerToken = request.Token;
        return Ok(new { Message = "令牌保存成功" });
    }

    public class TokenRequest
    {
        public string Token { get; set; }
    }
}

三、Flutter 前端配置(客户下单 + 店主获取FCM令牌)

  1. 添加依赖
    在pubspec.yaml中添加以下依赖:
dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.15.0
  firebase_messaging: ^14.6.5
  http: ^1.1.0

执行flutter pub get完成安装。

  1. 初始化Firebase
    在main.dart中初始化:
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}
  • Android:将google-services.json放入android/app目录。
  • iOS:将GoogleService-Info.plist放入ios/Runner目录,并在Xcode中添加到项目。
  1. 客户订单提交页面
    编写下单UI与逻辑:
class OrderSubmitPage extends StatefulWidget {
  const OrderSubmitPage({super.key});

  @override
  State<OrderSubmitPage> createState() => _OrderSubmitPageState();
}

class _OrderSubmitPageState extends State<OrderSubmitPage> {
  final _formKey = GlobalKey<FormState>();
  final _nameCtrl = TextEditingController();
  final _phoneCtrl = TextEditingController();
  final _pastryCtrl = TextEditingController();
  final _quantityCtrl = TextEditingController();
  final _addressCtrl = TextEditingController();

  Future<void> _submit() async {
    if (_formKey.currentState!.validate()) {
      final orderData = {
        'customerName': _nameCtrl.text,
        'telephoneNumber': _phoneCtrl.text,
        'pastryName': _pastryCtrl.text,
        'quantity': int.parse(_quantityCtrl.text),
        'address': _addressCtrl.text,
      };

      try {
        final response = await http.post(
          Uri.parse('http://你的后端地址/api/orders'),
          headers: {'Content-Type': 'application/json'},
          body: jsonEncode(orderData),
        );

        if (response.statusCode == 200) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('订单提交成功!')),
          );
          _formKey.currentState!.reset();
        } else {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('提交失败,请重试')),
          );
        }
      } catch (e) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('网络错误:$e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('提交订单')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                controller: _nameCtrl,
                decoration: const InputDecoration(labelText: '客户姓名'),
                validator: (val) => val!.isEmpty ? '请输入姓名' : null,
              ),
              TextFormField(
                controller: _phoneCtrl,
                decoration: const InputDecoration(labelText: '手机号'),
                validator: (val) => val!.isEmpty ? '请输入手机号' : null,
              ),
              TextFormField(
                controller: _pastryCtrl,
                decoration: const InputDecoration(labelText: '糕点名称'),
                validator: (val) => val!.isEmpty ? '请输入糕点名称' : null,
              ),
              TextFormField(
                controller: _quantityCtrl,
                decoration: const InputDecoration(labelText: '数量'),
                keyboardType: TextInputType.number,
                validator: (val) => val!.isEmpty ? '请输入数量' : null,
              ),
              TextFormField(
                controller: _addressCtrl,
                decoration: const InputDecoration(labelText: '配送地址'),
                validator: (val) => val!.isEmpty ? '请输入地址' : null,
                maxLines: 3,
              ),
              const SizedBox(height: 20),
              ElevatedButton(onPressed: _submit, child: const Text('提交订单')),
            ],
          ),
        ),
      ),
    );
  }
}
  1. 店主端获取FCM令牌
    编写令牌获取与上传逻辑:
class ShopOwnerPage extends StatefulWidget {
  const ShopOwnerPage({super.key});

  @override
  State<ShopOwnerPage> createState() => _ShopOwnerPageState();
}

class _ShopOwnerPageState extends State<ShopOwnerPage> {
  String? _fcmToken;

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

  Future<void> _fetchAndUploadToken() async {
    final token = await FirebaseMessaging.instance.getToken();
    setState(() => _fcmToken = token);
    
    if (token != null) {
      try {
        await http.post(
          Uri.parse('http://你的后端地址/api/owner/token'),
          headers: {'Content-Type': 'application/json'},
          body: jsonEncode({'token': token}),
        );
      } catch (e) {
        print('令牌上传失败:$e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('店主端')),
      body: Center(child: Text('FCM令牌:$_fcmToken')),
    );
  }
}

四、测试流程

  1. 店主打开Flutter店主端,获取并上传FCM令牌到后端。
  2. 客户打开订单页面,填写信息提交订单。
  3. 后端将订单保存到SQL Server,同时触发FCM通知发送到店主设备。
  4. 店主设备收到包含完整订单信息的通知。

内容的提问来源于stack exchange,提问作者Vitor Malaquias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:23:14