Validating emails with firebase for iOS - ios

When submitting a request to create a new user, if the user tries to submit with an invalid email, the app crashes (I.E. without an # sign). Is there a way to check if an email is valid through Firebase or is that something I need to validate app side?
The error I get in the console is:
* Terminating app due to uncaught exception 'InvalidEmail', reason: 'jfkdsla;fjdk is an invalid email address'
NSString *url = [NSString stringWithFormat:#"https://myapp.firebaseio.com/users/%#", displayName.text];
Firebase *dataRef = [[Firebase alloc] initWithUrl:url];
[dataRef observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
NSLog(#"Ref %#", snapshot.value);
snapshotValue = snapshot.value;
}];
if (snapshotValue == NULL) {
AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.authClient createUserWithEmail:email.text password:password.text andCompletionBlock:^(NSError* error, FAUser*user) {
if (error != nil) {
// Error
NSLog(#"ERROR CODE: %d",error.code);
NSLog(#"ERROR: %#",error);
if (error.code == -9999) {
email.textColor = [UIColor redColor];
}
} else {
NSLog(#"Created %#",user.userId);
Firebase *userRef = [[Firebase alloc] initWithUrl:[NSString stringWithFormat:#"https://myapp.firebaseio.com/users/%#",displayName.text]];
[[userRef childByAppendingPath:#"name"] setValue:fullName.text];
[[userRef childByAppendingPath:#"user_id"] setValue:user.userId];
Firebase *userCredentials = [[Firebase alloc] initWithUrl:[NSString stringWithFormat:#"https://myapp.firebaseio.com/users/%#/credentials",displayName.text]];
[[userCredentials childByAppendingPath:#"email"] setValue:email.text];
[[userCredentials childByAppendingPath:#"password"] setValue:password.text];
AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.authClient loginWithEmail:email.text andPassword:password.text
withCompletionBlock:^(NSError* error, FAUser* user) {
if (error != nil) {
NSLog(#"There was an error logging in to this account: %#",error);
} else {
NSLog(#"logged in");
[self dismissViewControllerAnimated:NO completion:nil];
[appDelegate.window.rootViewController presentViewController:appDelegate.tabBarController animated:YES completion:nil];
}
}];
}
}];
}
else {
displayName.textColor = [UIColor redColor];
}
}

Since an exception is being thrown, throw the "createUserWithEmail" line of code into a "#try{} / #catch{}" block:
#try {
[appDelegate.authClient createUserWithEmail:email.text password:password.text andCompletionBlock:^(NSError* error, FAUser*user) {
...
...
// keep that big huge block part intact
...
...
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
}

Related

gmail api full email access given the message id of email

I am trying to access the gmail messages in offline access mode. gmail access token I get from the server end.
I followed this link to here
I created my own authenticator class and subclass from GTMOAuth2Authentication and implemented the protocol as mentioned in the above link.
The canAutherize always fail and even though I make gmail query, It crashes in authorize function. Any help would be appreciated.
- (void)viewDidLoad {
[super viewDidLoad];
if ([self.subjectInfo length] > 0) {
[self.subjectLabel setText:self.subjectInfo];
}else {
[self.subjectLabel setText:#""];
}
self.service = [[GTLServiceGmail alloc] init];
[self fetchAccessToken];
// Initialize the Gmail API service & load existing credentials from the keychain if available.
}
// When the view appears, ensure that the Gmail API service is authorized, and perform API calls.
- (void)viewDidAppear:(BOOL)animated {
if (!self.service.authorizer.canAuthorize) {
// Not yet authorized, request authorization by pushing the login UI onto the UI stack.
// [self presentViewController:[self createAuthController] animated:YES completion:nil];
[self fetchAccessToken];
} else {
[self fetchMail:[self gmailMsgId]];
}
}
-(void) fetchAccessToken
{
[[APIManager sharedManager] fetchGmailToken:^(NSDictionary *resultDict) {
if (resultDict != nil) {
self.accessToken = [resultDict objectForKey:#"access_token"];
_authInst = [[GmailAuthenticator alloc] initWithAccessToken:self.accessToken];
self.service.authorizer = _authInst;
}
} failure:^(NSError *error) {
NSLog(#"fail to fetch access token");
}];
}
- (void)fetchMail:(NSString*)messageId {
GTLQueryGmail *query = [GTLQueryGmail queryForUsersMessagesGet];
query.messageId = messageId;
[self.service executeQuery:query
delegate:self
didFinishSelector:#selector(displayResultWithTicket:finishedWithObject:error:)];
}
- (void)displayResultWithTicket:(GTLServiceTicket *)ticket
finishedWithObject:(GTLGmailMessage *)messageResponse
error:(NSError *)error {
if (error == nil) {
NSLog(#"description is %#", [messageResponse description]);
} else {
NSLog(#"error : %#", [error description]);
}
}

ERROR: _block_literal_generic or _block_invoke

I'm having an issue finding the source of this crash in my iOS app which has a core data model using iPhone app i am not able to login URl. I am using same code on iOS 7 its working but now I am trying to work on iOS 8.2.Have issue for _block_literal_generic
Block point is below As well check screen shot for block Error:---
[[NetwokManager sharedInstance] loginRequestEmail:userEmail andPassword:userPassword WithResponse:^(id responseObject, NSError *error) { if (!error) {
}
Using code is below:
-(void)sendLoginRequest
{
NSString *userEmail = [[NSUserDefaults standardUserDefaults] objectForKey:#"emailKey"];
NSString *userPassword = [[NSUserDefaults standardUserDefaults] objectForKey:#"passwordKey"];
NSLog(#"Email %#", userEmail);
NSLog(#"Password %#", userPassword);
NSString *mobileNo = [SCUserProfile currentUser].callerid;
NSLog(#"CallerID %#", mobileNo);
[[NetwokManager sharedInstance] loginRequestEmail:userEmail andPassword:userPassword WithResponse:^(id responseObject, NSError *error) {
if (!error) {
NSLog(#"responseString = %#", responseObject);
if (responseObject == nil)
{
NSLog(#"No data from server");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"No data downloaded from server!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
}
NSDictionary *resposneDict = (NSDictionary*)responseObject;
NSString *success = [resposneDict valueForKey:#"success"];
if ([success isEqual:#"Authentication Failed"])
{
[self showAlertViewWithMessage:#"Authentication Failed"];
// [self sendLogoutRequest];
[[C2CallAppDelegate appDelegate] logoutUser];
}
else if ([success intValue] == 1)
{
amobilePayUserID = [resposneDict valueForKey:#"user_id"];
[[NSUserDefaults standardUserDefaults] setValue:amobilePayUserID forKey:#"AMobilePay_User_ID"];
NSLog(#"User Id is:= %#",amobilePayUserID);
}
else if ([success intValue] == 0)
{
//[self sendRegistrationRequest];
// [self sendLogoutRequest];
// [[C2CallAppDelegate appDelegate] logoutUser];
}
else
{
[self showAlertViewWithMessage:#"Unable to login AmobilePay"];
}
} else {
[self showAlertViewWithMessage:[error localizedDescription]];
}
}];
}
Crash in unknown region 2015-04-30 09:56:18.390 AmobipayMerchant[337:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MOC2CallEvent costs]: unrecognized selector sent to instance 0x16ef2dd0'
Somewhere in the code, you called costs to an instance of MOC2CallEvent. MOC2CallEvent has no method or property costs, so of course it will crash.

xcode 6: TwitterKit not keeping session open after Authentication

I'm calling up a session in my LoginViewController as seen below. The problem is that, after it authenticates and closes the popupview... the session returns nil. So it initially reaches out to the api and starts a session (the first log records nil as the session is open and the second log records "Signed in as..." with the username) then when it closes the login view it records nil again. Not exactly use what I could be doing wrong...
Could it be because I'm using TWTRSession* session to check the session? Could that be logging me off? Or is it related to me closing the popupview?
I do essentially the same thing with my facebook login but the facebook session stays open until I logout...
- (void)viewDidLoad
{
[super viewDidLoad];
self.email.delegate = self;
self.pass.delegate = self;
//self.view.frame = CGRectMake(self.bounds.size.width, self.bounds.size.height);
[Fabric with:#[[Twitter sharedInstance]]];
TWTRSession* session;
if (session) {
NSLog(#"Early bird %#", [session userName]);
[self closePopup];
}
else {
NSLog(#"No dice");
}
/*
TWTRLogInButton *logInButton = [TWTRLogInButton buttonWithLogInCompletion:^(TWTRSession *session, NSError *error) {
// play with Twitter session
}];
logInButton.center = self.view.center;
[self.view addSubview:logInButton];
*/
TWTRLogInButton* logInButton = [TWTRLogInButton
buttonWithLogInCompletion:
^(TWTRSession* session, NSError* error) {
if (session) {
NSLog(#"signed in as %#", [session userName]);
[self closePopup];
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
I decided to include my actionsheet as well so you could see how I'm handling the login/logout situation:
- (void)sheet: (id) sender {
NSString *email = [[NSUserDefaults standardUserDefaults] objectForKey:#"email"];
UIActionSheet *sheet;
TWTRSession *session;
//if ([FBSDKAccessToken currentAccessToken]) {
if (email == nil && [FBSDKAccessToken currentAccessToken] == nil && session == nil) {
sheet = [[UIActionSheet alloc] initWithTitle:#"Profile"
delegate:nil // Can be another value but will be overridden when showing with handler.
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Login"
otherButtonTitles:nil];
}
else
{
sheet = [[UIActionSheet alloc] initWithTitle:#"Profile"
delegate:nil // Can be another value but will be overridden when showing with handler.
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Logout"
otherButtonTitles:#"User page", nil];
}
[sheet showInView:self.view
handler:^(UIActionSheet *actionSheet, NSInteger buttonIndex) {
if (buttonIndex == [actionSheet cancelButtonIndex]) {
NSLog(#"Cancel button index tapped");
} else if (buttonIndex == [actionSheet destructiveButtonIndex]) {
if (email == nil && [FBSDKAccessToken currentAccessToken] == nil && session == nil) {
LoginViewController *loginView = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
//[self.view modalViewController:loginView animated:YES];
//[self presentModalViewController:loginView animated:YES];
//[self.navigationController pushViewController:loginView animated:YES];
loginView.delegate = (id) self;
[self presentPopupViewController:loginView animationType:MJPopupViewAnimationSlideTopBottom];
NSLog(#"Login View");
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:#"email"];
FBSDKLoginManager *logout = [[FBSDKLoginManager alloc] init];
[logout logOut];
}
} else {
NSLog(#"Button %i tapped", buttonIndex);
if (buttonIndex == 1) {
UserViewController * userView = [[UserViewController alloc] initWithNibName:#"UserView" bundle:[NSBundle mainBundle]];
[userView setUEmail:email];
[self presentViewController:userView animated:YES completion:nil];
}
}
}];
}
So I ended up creating my own custom IBAction to handle twitter logins. This works much better. Basically you just have to be careful with how you check if a session is active:
-(IBAction)twlogin:(id)sender
{
[Fabric with:#[[Twitter sharedInstance]]];
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
if (session) {
NSLog(#"signed in as %#", [session userName]);
TWTRShareEmailViewController* shareEmailViewController =
[[TWTRShareEmailViewController alloc]
initWithCompletion:^(NSString* email2, NSError* error) {
NSLog(#"Email %#, Error: %#", email2, error);
}];
[self presentViewController:shareEmailViewController
animated:YES
completion:nil];
[self closePopup];
NSLog(#"session check %#", [session userName]);
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
[[Twitter sharedInstance] logOut];
}
As you can see TWTR *session has to be included with Twitter shared instance like so:
[[Twitter sharedInstance] logInWithCompletion:^
(TWTRSession *session, NSError *error) {
I didn't do that before, and that's why it wasn't working. Hopefully this helps someone. (now if someone would help me getting Twitter emails to work... that would be greatly appreciated...)

Unable to download the note attachmet using Evernote IOS SDK

I have integrated the latest evernote ios sdk from github, That support both regular user and also business user. I can able to list the note book and notes without any issues but when i try to download the note attachment its giving me the following error.
Error Domain=ENErrorDomain Code=1 "Missing result: getResourceData
failed: unknown result" UserInfo=0x10dcb15f0
{NSLocalizedDescription=Missing result: getResourceData failed:
unknown result} Skipping field: due to type mismatch
(received:11)
Here the code i have used to download the note attachment.
+ (void)downloadDataWithNoteBook:(ENNotebook *)notebook fromNoteResource:(EDAMResource *)resource
onCompletion:(ZIdResultBlock)block {
ENPreferencesStore *preference = [ENSession sharedSession].preferences;
ENNoteStoreClient *noteStoreClient = [preference objectForKey:[SEEvernoteHelper getTitleForNoteAttachments:resource]];
NSString *str = resource.guid;
NSLog(#"GUID = [%#]", resource.guid);
[noteStoreClient getResourceDataWithGuid:resource.guid success:^(NSData *data) {
if(block) {
block(data, nil);
}
}
failure:^(NSError *error) {
if (block) {
block(nil, error);
}}];
}
Finally i was able to do it!!!
Here is my code:
//select the file that you want to download from evernote
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
isParentNoteBooks = false;
if ([SEEvernoteHelper isNoteBookInstance:[self.datasourceObjects objectAtIndex:indexPath.row]]) {
self.selectedNoteBook = [self.datasourceObjects objectAtIndex:indexPath.row];
[self fetchAttachmentsForNoteBook:[self.datasourceObjects objectAtIndex:indexPath.row]];
// set here if the notebook is business or not.
if ([SEEvernoteHelper isBussinessNoteBook:self.selectedNoteBook]) {
isCurrentNoteBookBusiness = YES;
}
else{
isCurrentNoteBookBusiness = NO;
}
} else {
self.selectedFileNameToDownload = [SEEvernoteHelper getTitleForNoteAttachments:[self.datasourceObjects objectAtIndex:indexPath.row]];
self.selectedResource = [self.datasourceObjects objectAtIndex:indexPath.row];
[self downloadNoteResultObject:self.selectedResource];
}
}
//start the download process
- (void)downloadNoteResultObject:(id)resultObject {
MBProgressHUD *HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.labelText = kStrDownloadingLabel;
HUD.detailsLabelText = self.selectedFileNameToDownload;
__weak __typeof__(self) weakSelf = self;
[SEEvernoteHelper downloadDataWithNoteBook:self.selectedNoteBook fromNoteResource:resultObject onCompletion:^(id result, NSError *error) {
if (result) {
[NSThread syncOnMain:^{
//save the downloaded data....
[HUD hide:YES];
}];
} else {
[HUD hide:YES];
[NSThread syncOnMain:^{
//error
}];
}
}];
}
//get the download file
+ (void)downloadDataWithNoteBook:(ENNotebook *)notebook fromNoteResource:(EDAMResource *)resource onCompletion:(ZIdResultBlock)block {
ENNoteStoreClient *noteStoreClient = [[ENSession sharedSession] noteStoreForNotebook:notebook];
[noteStoreClient getResourceWithGuid:resource.guid withData:YES withRecognition:NO withAttributes:YES withAlternateDate:NO success:^(EDAMResource *resource) {
if(block) {
block(resource.data.body, nil);
}
} failure:^(NSError *error) {
NSLog(#"Error : %#",error);
if (block) {
block(nil, error);
}
}];
}

Instance method not found callDelegateOnMainThread

I'm getting the error instance method '-callDelegateOnMainThread:withArg:error:' not found what should I do here? I merged in some achievement code into Ray Wenderlichs turn based multiplayer code.
The functions are part of the following interface:
#interface GCTurnBasedMatchHelper : NSObject <GKTurnBasedMatchmakerViewControllerDelegate, GKTurnBasedEventHandlerDelegate, GKAchievementViewControllerDelegate, MFMessageComposeViewControllerDelegate> {
BOOL gameCenterAvailable;
BOOL userAuthenticated;
UIViewController *presentingViewController;
NSMutableDictionary* earnedAchievementCache;
GKTurnBasedMatch *currentMatch;
//id <GCTurnBasedMatchHelperDelegate> delegate;
}
Here are the functions
- (void) submitAchievement: (NSString*) identifier percentComplete: (double) percentComplete
{
//GameCenter check for duplicate achievements when the achievement is submitted, but if you only want to report
// new achievements to the user, then you need to check if it's been earned
// before you submit. Otherwise you'll end up with a race condition between loadAchievementsWithCompletionHandler
// and reportAchievementWithCompletionHandler. To avoid this, we fetch the current achievement list once,
// then cache it and keep it updated with any new achievements.
if(self.earnedAchievementCache == NULL)
{
[GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error)
{
if(error == NULL)
{
NSMutableDictionary* tempCache = [NSMutableDictionary dictionaryWithCapacity: [scores count]];
for (GKAchievement* score in scores)
{
[tempCache setObject: score forKey: score.identifier];
}
self.earnedAchievementCache = tempCache;
[self submitAchievement: identifier percentComplete: percentComplete];
}
else
{
//Something broke loading the achievement list. Error out, and we'll try again the next time achievements submit.
[self callDelegateOnMainThread: #selector(achievementSubmitted:error:) withArg: NULL error: error];
}
}];
}
else
{
//Search the list for the ID we're using...
GKAchievement* achievement = [self.earnedAchievementCache objectForKey: identifier];
if(achievement != NULL)
{
if((achievement.percentComplete >= 100.0) || (achievement.percentComplete >= percentComplete))
{
//Achievement has already been earned so we're done.
achievement= NULL;
}
achievement.percentComplete= percentComplete;
}
else
{
achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
achievement.percentComplete= percentComplete;
//Add achievement to achievement cache...
[self.earnedAchievementCache setObject: achievement forKey: achievement.identifier];
}
if(achievement != NULL)
{
//Submit the Achievement...
[achievement reportAchievementWithCompletionHandler: ^(NSError *error)
{
[self callDelegateOnMainThread: #selector(achievementSubmitted:error:) withArg: achievement error: error];
}];
}
}
}
- (void) achievementSubmitted: (GKAchievement*) ach error:(NSError*) error;
{
if((error == NULL) && (ach != NULL))
{
if (ach.percentComplete == 100.0) {
//UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Achievement Earned!"
// message:(#"%#",ach.identifier)
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles:nil];
//[alert show];
//[alert release];
TRACE("achievement submitted %s\n", [ach.identifier UTF8String]);
}
}
else
{
// Achievement Submission Failed.
printf("Achievement Submission Failed\n");
}
}
Looks like this is the missing code you are looking for. Just put it inside of your GCTurnBasedMatchHelper.m file.
- (void) callDelegateOnMainThread: (SEL) selector withArg: (id) arg error: (NSError*) err
{
dispatch_async(dispatch_get_main_queue(), ^(void)
{
[self callDelegate: selector withArg: arg error: err];
});
}
- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
assert([NSThread isMainThread]);
if([delegate respondsToSelector: selector])
{
if(arg != NULL)
{
[delegate performSelector: selector withObject: arg withObject: err];
}
else
{
[delegate performSelector: selector withObject: err];
}
}
else
{
NSLog(#"Missed Method");
}
}
Just add the method which doesn't exist.

Resources