Python中Firebase流处理函数未正确更新全局变量问题排查
问题分析与修复方案
我来帮你拆解下代码里的几个关键问题,正是这些问题导致全局变量没正确更新,最后推送的代码也没执行:
1. 条件判断的时机完全错了
你写的if value is 1 & value1 is 1:这段代码,是在启动Firebase流监听之前就同步执行了!这时候value和value1还是初始的0,所以不管后续回调怎么更新这两个变量,这段判断代码都不会再跑一遍。Firebase的stream()是异步监听数据变化的,回调函数只有在数据真的改变时才会被触发,而主程序的初始判断早就执行完了。
2. 用错了比较运算符
在Python里,is是用来判断两个对象是不是同一个内存地址的,不是用来比较数值相等的!Firebase返回的message['data']可能是整数1,也可能是字符串'1'(取决于你在Firebase里的存储类型),用is 1大概率会判断失败。正确的做法是用==来比较值:
if message['data'] == 1: # 要是存的是字符串就改成 == '1'
另外,你用了&(按位与)来做逻辑判断,这也不对,应该用and(逻辑与),&是二进制位运算符号,放在这里会导致逻辑错误:
if value == 1 and value1 == 1:
3. 回调里的return完全没用
stream_handler和stream_handler1里的return value纯粹是多余的,Firebase的流回调根本不需要返回值,你只要在回调里给全局变量赋值就行,不用返回。
修复后的完整代码
把推送的判断逻辑放到回调里,每次更新变量后就检查是否满足两个值都是1的条件:
value = 0 value1 = 0 def send_fall_notification(): # 把推送逻辑抽出来,复用代码 if value == 1 and value1 == 1: response = pn_client.publish( interests=['hello'], publish_body={ 'apns': { 'aps': { 'alert': 'Hello!', }, }, 'fcm': { 'notification': { 'title': 'Notification', 'body': 'Fall Detected !!', }, }, }, ) print(response['publishId']) def stream_handler(message): global value print(message) # 这里根据你Firebase里存的类型调整,是数字就用==1,是字符串就用=='1' if message['data'] == 1: value = 1 else: value = 0 # 更新完立刻检查是否要发推送 send_fall_notification() def stream_handler1(message1): global value1 print(message1) if message1['data'] == 1: value1 = 1 else: value1 = 0 # 更新完立刻检查是否要发推送 send_fall_notification() # 启动Firebase流监听 my_stream = db.child("Fall_Detection_Status").stream(stream_handler) my_stream1 = db.child("Fall_Detection_Status1").stream(stream_handler1) # 脚本环境下要加这个循环保持程序运行,不然启动流后程序直接退出 import time while True: time.sleep(1)
额外提醒
- 一定要确认Firebase里
Fall_Detection_Status和Fall_Detection_Status1的存储类型:如果是字符串"1",就把判断条件改成== '1',不然会判断失败。 - 最后的
while True循环是必须的,因为脚本启动流后如果没有阻塞代码,会立刻退出,根本没法监听后续的数据变化。
内容的提问来源于stack exchange,提问作者Moustapha Sabbagh
相关产品推荐
相关产品推荐

