所以我是使用Firebase和iOS应用开发的新手,我正在尝试按照guide.
设置简单登录出于某种原因,尽管完成块代码永远不会被执行,并且我用来查看用户创建是否正常的bool始终为NO。我尝试使用调试器逐步执行我的代码,当它到达完成块时,它基本上只是跳到方法的结尾,非常奇怪的行为。这是我的代码:
BOOL goodFirebaseCall = false;
- (void)createUser:(NSString*)userName andPasswordis:(NSString*)password {
goodFirebaseCall = [self createFirebaseUser:userName andPasswordis:password];
if(goodFirebaseCall==true) //goodFirebaseCall is always NO
{
NSLog(@"Logged in, now adding the user to Firebase.");
// Create a reference to a Firebase location
Firebase* fUsers = [[Firebase alloc] initWithUrl:@"https://xxxx.firebaseio.com/users"];
Firebase* fNewUser = [fUsers childByAppendingPath:userName]; //childByAutoId];
[fNewUser setValue:@{@"name":userName}];
}
else
{
NSLog(@"Error, something went wrong with user creation");
}
}
-(BOOL)createFirebaseUser:(NSString*)email andPasswordis:(NSString*)password
{
goodFirebaseCall = false;
Firebase* myRef = [[Firebase alloc] initWithUrl:@"https://xxxx.firebaseio.com/"];
FirebaseSimpleLogin* authClient = [[FirebaseSimpleLogin alloc] initWithRef:myRef];
[authClient createUserWithEmail:@"email@domain.com" password:@"very secret"
andCompletionBlock:^(NSError* error, FAUser* user) {
if (error != nil) {
// There was an error creating the account
NSLog(@"%@", error);
} else {
// We created a new user account
goodFirebaseCall = true;
NSLog(@"User Created!");
}
}];
return goodFirebaseCall;
}
对此问题的任何帮助将不胜感激!我一直在摸不着为什么完整区块永远不会被召唤。
谢谢, NuttGuy
答案 0 :(得分:3)
您似乎正在尝试同步使用createUserWithEmail:password
,但实际上异步执行完成块。这允许Firebase在后台运行而不会挂起您的UI。这意味着您希望在 createUser调用之后运行的代码应在完成块中。您还可以使用完成块调用另一个方法来完成所需的任何额外用户创建。
您可以像这样构建代码:
- (void)createUser:(NSString *)userName
withEmail:(NSString *)email
andPassword:(NSString *)password {
[self createFirebaseUser:userName withEmail:email andPassword:password];
}
- (void)createFirebaseUser:userName
withEmail:(NSString *)email
andPassword:(NSString *)password {
Firebase* myRef = [[Firebase alloc] initWithUrl:@"https://xxxx.firebaseio.com/"];
FirebaseSimpleLogin* authClient = [[FirebaseSimpleLogin alloc] initWithRef:myRef];
[authClient createUserWithEmail:email password:password
andCompletionBlock:^(NSError* error, FAUser* user) {
if (error != nil) {
// There was an error creating the account
NSLog(@"%@", error);
[self completeCreateUser:userName
withFirebaseUser:user ifFirebaseSucceeds:NO];
} else {
NSLog(@"User Created! %@", user);
[self completeCreateUser:userName
withFirebaseUser:user ifFirebaseSucceeds:YES];
}
}];
}
- (void)completeCreateUser:(NSString *)userName
withFirebaseUser:(FAUser *)user
ifFirebaseSucceeds:(BOOL)goodFirebaseCall {
if (goodFirebaseCall) {
NSLog(@"User created, but not logged in, now adding the user to Firebase.");
// Create a reference to a Firebase location
Firebase* fUsers = [[Firebase alloc] initWithUrl:@"https://xxxx.firebaseio.com/users"];
Firebase* fNewUser = [fUsers childByAppendingPath:user.uid]; //childByAutoId];
[fNewUser setValue:@{@"name":userName}];
} else {
NSLog(@"Error, something went wrong with user creation");
}
}
所以你看到它与goodFirebaseCall
周围的if语句相同,但是不是等待返回BOOL
,而是从完成块调用另一个方法并传递它您想要的BOOL
"已退回。"
我试图保持代码相同,以便您可以看到段移动的位置,但如果您愿意,可以将所有代码放在完成块内的第三个方法中。我修改过的一件事就是使用user.uid
作为Firebase用户引用的附加路径,因为您的安全规则和FAUser
对象始终可以访问这些对象,您可以从中获取登录等。
此外,createUserWithEmail:password
将不登录您的用户。您必须在loginWithEmail:andPassword:withCompletionBlock:
完成块内或第三种方法中再次拨打createUserWithEmail:password
。