我试图在IOS中使用firebase建立一个聊天室。当我在firebase控制台的模拟器中测试但在IOS应用程序中不起作用时,工作正常。
我使用的结构是这样的
根/构件/间-ID / auth.uid /用户数据
根/消息/ ROOM_ID /消息/消息
我在IOS中用
创建了一个新房间- (void)initRoom
{
NSMutableDictionary *mdata = [[NSMutableDictionary alloc] init];
FIRUser *user = [FIRAuth auth].currentUser;
mdata[@"uid"] = user.uid;
// get the key for the new room
roomKey = [[_rootRef child:@"messages"] childByAutoId].key;
if (roomKey != nil) {
// add auth.uid to member/roomkey
NSString *memberID = [[[_rootRef child:@"members"] child: roomKey ] child: user.uid ].key;
[[[[_rootRef child:@"members"] child: roomKey ] child: memberID ] setValue:mdata];
[self addMemberToRoom];
}
}
并为该房间添加其他成员(目前使用硬编码的uid):
-(void) addMemberToRoom{
NSString *memberID = [[[_rootRef child:@"members"] child: roomKey ] child: @"QLfRoGpoCjWpzira7fljBj8g3EJ3"].key;
NSMutableDictionary *mdata = [[NSMutableDictionary alloc] init];
mdata[@"uid"] = @"QLfRoGpoCjWpzira7fljBj8g3EJ3";
if (memberID !=nil) {
[[[[_rootRef child:@"members"] child: roomKey ] child: memberID ] setValue:mdata];
}
// start listener
[self observeMessages];
}
并像这样启动监听器:
-(void)observeMessages
{
_msgHandle = [[[_rootRef child:@"messages"] child: roomKey] observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) {
NSDictionary<NSString *, NSString *> *message = snapshot.value;
NSString *name = message[@"senderId"];
NSString *text = message[@"message"];
[self addMessagewithId:name andText:text];
// animates the receiving of a new message on the view
[self finishReceivingMessage];
}];
}
当我设置这样的规则时,这一切都很好地向数据库添加消息并在应用程序中看到它:
{
"rules": {
"members": {
".read": "auth !== null",
".write": "auth !== null",
},
"messages": {
".write":"auth !== null",
".read": "auth !== null",
"$room_id": {
}
}
}
}
现在,由于我不希望每个人都能阅读这些消息,我将规则设置为:
{
"rules": {
"members": {
".read": "auth !== null",
".write": "auth !== null",
},
"messages": {
".write": "auth !== null",
"$room_id": {
".read": "root.child('members/'+$room_id+'/'+auth.uid).exists()",
}
}
}
}
当我这样做时,IOS应用程序中的监听器将不会收到任何呼叫。使用firebase控制台中的模拟器检查从应用程序创建的room_id和用户,读取标记为OK。
我的假设是,在创建新成员之前初始化了监听器,但即使推迟初始化也无济于事。
你能指点我正确的方向帮助我吗?非常感谢!
答案 0 :(得分:0)
好的,我找到了一个现在有效的解决方案。聊天室的观察者是在成员列表中聊天室可用之前创建的,因此.read规则返回false。
我的解决方法是将一个观察者设置为成员列表,该列表在触发时启动消息的观察者。
这是我的代码:
-(void) getLastRoom // invoked when new room is added to members node
{
FIRUser *user = [FIRAuth auth].currentUser;
NSString *uid = user.uid;
_msgHandle = [[[[_rootRef child:@"members"] child: roomKey] queryEqualToValue: uid] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
NSString *chatRoom = snapshot.key; //-> returns the roomkey of the chatroom
if ([chatRoom isEqualToString:roomKey]){
[self observeMessages];
}
}];
}
希望它可能对某人有所帮助。