无需Firebase,从SQL Server向设备发送Flutter推送通知的实现方法
无需Firebase实现SQL Server到设备的推送通知
完全可以不依赖Firebase,通过自有服务器API对接各平台原生推送服务来实现。核心逻辑是:SQL Server触发推送事件 → 自有API服务器处理请求 → 调用对应平台的推送接口 → 设备接收通知。以下是具体实现步骤:
1. 对接各平台原生推送服务
不同平台的推送机制不同,需分别配置:
- iOS(APNs):
- 在苹果开发者后台创建APNs密钥,获取
Team ID、Bundle ID和密钥文件。 - 采用Token认证方式(比证书更易维护),生成JWT令牌用于请求APNs接口。
- 在苹果开发者后台创建APNs密钥,获取
- Android:
- 海外用户:直接调用FCM的HTTP API,无需在服务器集成Firebase SDK,只需在Firebase控制台获取服务器密钥。
- 国内用户:对接小米、华为、OPPO等厂商推送平台,各厂商有独立的API和认证流程,需在对应开发者平台完成配置。
2. 搭建自有API服务器
作为中间层,负责接收SQL Server的推送请求并转发到对应平台接口。以下是C#实现的核心示例:
APNs推送代码示例
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using Newtonsoft.Json; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; public async Task SendApplePush(string deviceToken, string title, string body) { var apnsAuthKey = Environment.GetEnvironmentVariable("APNS_AUTH_KEY"); var teamId = Environment.GetEnvironmentVariable("APNS_TEAM_ID"); var bundleId = Environment.GetEnvironmentVariable("APNS_BUNDLE_ID"); // 生成APNs JWT令牌 var securityKey = new SymmetricSecurityKey(Convert.FromBase64String(apnsAuthKey)); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var jwtToken = new JwtSecurityToken(issuer: teamId, expires: DateTime.UtcNow.AddMinutes(20), signingCredentials: credentials); var jwt = new JwtSecurityTokenHandler().WriteToken(jwtToken); // 构造推送请求 using var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); httpClient.DefaultRequestHeaders.Add("apns-topic", bundleId); var payload = new { aps = new { alert = new { title, body }, sound = "default" } }; var jsonPayload = JsonConvert.SerializeObject(payload); var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync($"https://api.push.apple.com/3/device/{deviceToken}", content); response.EnsureSuccessStatusCode(); }
Android FCM推送代码示例
public async Task SendAndroidPush(string deviceToken, string title, string body) { var fcmServerKey = Environment.GetEnvironmentVariable("FCM_SERVER_KEY"); using var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("key", fcmServerKey); var payload = new { to = deviceToken, notification = new { title, body }, data = new { orderId = "12345" } // 自定义业务数据 }; var jsonPayload = JsonConvert.SerializeObject(payload); var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync("https://fcm.googleapis.com/fcm/send", content); response.EnsureSuccessStatusCode(); }
3. SQL Server触发推送请求
SQL Server不适合直接调用外部API(易阻塞事务),推荐用任务表+异步处理的方式:
步骤1:创建推送任务表
CREATE TABLE PushTasks ( Id INT IDENTITY(1,1) PRIMARY KEY, DeviceToken NVARCHAR(255) NOT NULL, Platform NVARCHAR(10) NOT NULL, -- 标记iOS/Android Title NVARCHAR(100) NOT NULL, Body NVARCHAR(500) NOT NULL, CreatedAt DATETIME DEFAULT GETUTCDATE(), IsProcessed BIT DEFAULT 0, ProcessedAt DATETIME );
步骤2:创建触发器插入任务
当业务数据变更时,将推送任务插入到任务表:
CREATE TRIGGER trg_OrderStatusUpdated ON Orders AFTER UPDATE AS BEGIN SET NOCOUNT ON; -- 仅当状态字段更新时触发 IF UPDATE(Status) BEGIN INSERT INTO PushTasks (DeviceToken, Platform, Title, Body) SELECT c.DeviceToken, c.Platform, '订单状态更新', CONCAT('你的订单 ', i.OrderNumber, ' 已变为: ', i.Status) FROM inserted i JOIN Customers c ON i.CustomerId = c.Id WHERE c.DeviceToken IS NOT NULL; END END
步骤3:异步处理任务
编写独立服务(如.NET Worker Service)或使用SQL Server代理作业,轮询PushTasks表处理未完成的推送任务:
// 简化的轮询逻辑 while (true) { var tasks = GetUnprocessedPushTasks(); // 查询IsProcessed=0的任务 foreach (var task in tasks) { try { if (task.Platform == "iOS") await SendApplePush(task.DeviceToken, task.Title, task.Body); else if (task.Platform == "Android") await SendAndroidPush(task.DeviceToken, task.Title, task.Body); MarkTaskAsProcessed(task.Id); // 更新任务状态为已处理 } catch (Exception ex) { // 记录错误日志,可设置重试机制或标记任务失败 LogError(ex, task.Id); } } await Task.Delay(TimeSpan.FromSeconds(10)); // 每10秒轮询一次 }
关键注意事项
- 异步优先:禁止在SQL触发器中直接调用外部API,避免阻塞主业务事务,引发性能问题。
- Token有效性:推送失败时需处理Token过期或无效的情况,及时从数据库移除或更新无效Token。
- 安全防护:APNs密钥、FCM服务器密钥等敏感信息通过环境变量或配置中心管理,禁止硬编码。
- 合规性:遵守各平台推送规则,比如iOS需用户授权通知权限,Android需配置通知渠道。
内容的提问来源于stack exchange,提问作者alper
相关产品推荐
相关产品推荐

