简体   繁体   English

无法使用通过电子邮件/密码的Firebase简单登录来执行完成阻止

[英]Can't get Completion Block to execute using Firebase Simple Login with Email/Password

So I'm new to using Firebase, and iOS app development, and am trying to set up Simple Login following this guide. 因此,我不熟悉使用Firebase和iOS应用程序开发,并且正在尝试按照本指南设置简单登录

For some reason though the completion block code never gets executed and a bool that i'm using to see if the user creation went okay is always NO. 由于某些原因,尽管完成块代码从未执行过,并且我用来查看用户创建是否正常的布尔值始终为NO。 I tried to step through my code using the Debugger and when it got to the completion block it basically just jumped to the end of the method, very odd behavior. 我试图使用调试器逐步检查代码,当它到达完成块时,它基本上只是跳到了方法的结尾,这是非常奇怪的行为。 Here is my code: 这是我的代码:

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;
}

Any help on this problem would be greatly appreciated! 在这个问题上的任何帮助将不胜感激! I've been scratching my head as to why the completion block would never get called. 我一直在摸索为什么永远不会调用完成模块。

Thanks, NuttGuy 谢谢,NuttGuy

It looks like you're trying to use createUserWithEmail:password synchronously, but completion blocks are actually executed asynchronously. 看起来您正在尝试同步使用createUserWithEmail:password ,但是完成块实际上是异步执行的。 This allows Firebase to operate in the background and not hang your UI. 这使Firebase可以在后台运行,而不会挂起UI。 This means that code you want run after the createUser call should be inside the completion block. 这意味着您要 createUser调用之后运行的代码应位于完成块内。 You could also use the completion block to call into another method that completes any extra user creation you want. 您也可以使用完成块来调用另一个方法,该方法可以完成所需的任何其他用户创建。

You can structure your code like this: 您可以像下面这样构造代码:

- (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");
    }
}

So you see that it's the same if-statement surrounding goodFirebaseCall , but instead of waiting for the BOOL to be returned, you call another method from the completion block and pass it the BOOL you want "returned." 因此,您看到围绕goodFirebaseCall if语句是相同的,但是您无需等待BOOL返回,而是从完成块中调用另一个方法,然后将您要“返回”的BOOL传递给它。

I tried to keep the code the same so that you could see where the segments moved, but you could put all of the code in the third method inside of the completion block if you wanted to. 我试图使代码保持相同,以便可以看到段移动的位置,但是如果需要,可以将所有代码放在完成块内部的第三个方法中。 The one thing I did modify was to use user.uid as the path appended to the Firebase users reference since that will always be accessible in your security rules and on FAUser objects, which you'll get from logging in and such. 我所做的一件事是使用user.uid作为Firebase用户引用的附加路径,因为在您的安全规则和FAUser对象中始终可以访问该路径,您可以通过登录等方式获得该路径。

Also, createUserWithEmail:password will not log in your user. 此外, createUserWithEmail:password不会登录您的用户。 You will have to make another call to loginWithEmail:andPassword:withCompletionBlock: either inside the createUserWithEmail:password completion block, or in the third method. 您将必须在createUserWithEmail:password完成块中或在第三个方法中再次调用loginWithEmail:andPassword:withCompletionBlock:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM