Welcome to the Friendly Chat codelab. In this codelab, you'll learn how to use the Firebase platform to create iOS applications. You will implement a chat client, and monitor its performance using Firebase.

This codelab is also available in Swift.

What you'll learn

What you'll need

How will you use this tutorial?

Read it through only Read it and complete the exercises

How would rate your experience with building iOS apps?

Novice Intermediate Proficient

Clone the GitHub repository from the command line.

$ git clone https://github.com/firebase/friendlychat-ios

To build the starter app:

  1. In a terminal window, navigate to the grow-ios-starter/objc-starter directory from your sample code download
  2. Run pod install
  3. Open the FriendlyChatObjc.xcworkspace file to open the project in Xcode.

Create project

From Firebase console select Add Project.

Call the project FriendlyChat, then click on Create Project.

Connect your iOS app

  1. From the Project Overview screen of your new project, click Add Firebase to your iOS app.
  2. Enter the bundle ID, as "com.google.firebase.codelab.FriendlyChatObjC".
  3. Click Register App.

Add GoogleService-Info.plist file to your app

On the second screen click Download GoogleService-Info.plist to download a configuration file that contains all the necessary Firebase metadata for your app. Copy that file to your application and add it to the FriendlyChatObjC target.

You can now click the "x" in the upper right corner of the popup to close it -- skipping steps 3 and 4 -- as you will perform those steps here.

Use Rules To Restrict To Authenticated Users

We will now add a rule to require authentication before reading or writing any messages. To do this we add the following rules to our messages data object. From within the Database section of Firebase console select the RULES tab. Then update the rules so they look like this:

{
  "rules": {
        "messages": {
            ".read": "auth != null",
            ".write": "auth != null"
        }
  }
}

For more information on how this works (including documentation on the "auth" variable) see the Firebase security documentation.

Configure Authentication APIs

Before your application can access the Firebase Authentication APIs on behalf of your users, you will have to enable it

  1. Navigate to the Firebase console and select your project
  2. Select Authentication
  3. Select the Sign In Method tab
  4. Toggle the Google switch to enabled (blue)
  5. Press Save on the resulting dialog

If you get errors later in this codelab with the message "CONFIGURATION_NOT_FOUND", come back to this step and double check your work.

Setup your Info.plist for Google Sign In.

You'll need to add a custom URL scheme to your XCode project.

  1. Open your project configuration: double-click the project name in the left tree view. Select your app from the TARGETS section, then select the Info tab, and expand the URL Types section.
  2. Click the + button, and add a URL scheme for your reversed client ID. To find this value, open the GoogleService-Info.plist configuration file, and look for the REVERSED_CLIENT_ID key. Copy the value of that key, and paste it into the URL Schemes box on the configuration page. Leave the other fields blank.
  3. When completed, your config should look something similar to the following (but with your application-specific values):

Test the working starter app:

  1. Click the Run button.
  2. Sign in and add a few messages to confirm that the app works as expected.

Firebase In-App Messaging helps you engage your app's active users by sending them targeted, contextual messages that encourage them to use key app features.

Confirm Firebase InAppMessaging dependency

Confirm the pod 'Firebase/InAppMessagingDisplay' dependency exists in your Podfile file.

Add debug flag to your project

Device testing requires a FirebaseInstanceID. Find your testing app's Instance ID by running the app with the runtime command argument -FIRDebugEnabled, and looking for the following line in the Xcode console's logs:

[Firebase/InAppMessaging][I-IAM180017] Starting InAppMessaging runtime with Instance ID YOUR_APP_ID

Go to Product > Scheme > Edit Scheme. Then select the Arguments tab and add the flag to `Arguments passed on launch`

Get your app's Instance ID

Click the Run button. Then search for the line with "Starting InAppMessaging" in the Xcode console. Make note of the Instance ID.

Create in app message

From the Firebase console, select `In-App Messaging` from the navigation panel. Select `Start your first campaign`. Enter "Welcome back" for the title and "Good to see you again" for the body. Then click Test on your Device. Enter the Instance ID in the available field and click the + sign to add it. Then click Test.

Test In-App Messaging

  1. Close your app if opened.
  2. Open your app.
  3. Confirm that a modal dialog displays a message with the title and body we entered in the console.

Firebase Analytics provides a way for you to understand the way users move through your application, where they succeed and where they get stuck and turn back. It can also be used to understand the most used parts of your application.

Initialize Measurement

Add measurement helper methods.

MeasurementHelper.m

+ (void)sendLoginEvent {
  [FIRAnalytics logEventWithName:kFIREventLogin parameters:nil];
}

+ (void)sendLogoutEvent {
  [FIRAnalytics logEventWithName:@"logout" parameters:nil];
}

+ (void)sendMessageEvent{
  [FIRAnalytics logEventWithName:@"message" parameters:nil];
}

If you want to view this activity in your Firebase console, select Product ... Scheme... Edit Scheme in Xcode. In the Arguments Passed on Launch section, click the + to add a new argument and add add -FIRAnalyticsDebugEnabled as the new argument.

Firebase Crashlytics allows your application to report when crashes occur and log the events leading up to the crash.

Confirm Firebase Crashlytics dependency

Confirm that pod 'Fabric', '~> 1.7.2' and pod 'Crashlytics', '~> 3.9.3' dependencies exist in your Podfile file.

Add the run script build phase

  1. Open your project in Xcode and select its project file in the Navigator.
  2. Open the Build Phases tab.
  3. Click + Add a new build phase, and select New Run Script Phase.
  4. Add the following line to the Type a script... text box:
${PODS_ROOT}/Fabric/run
  1. If you are using XCode 10 then add your app's built Info.plist location to the Build Phase's Input Files field.
$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)
  1. Generally you would only want to upload debug symbol files for release versions of you application. However for this codelab upload debug symbol files for debug builds. In the Xcode Navigator, open the Build Settings tab. Search for "debug information format". Then set the Debug Information Format setting to DWARF with dSYM File.

Initiate crash

FCViewController.m

- (IBAction)didPressCrash:(id)sender {
  [[Crashlytics sharedInstance] crash];
}

Test Firebase Crashlytics

  1. Click Build and then run the current scheme in Xcode to build your app on a device or simulator.
  2. Click Stop running the scheme or action in Xcode to close the initial instance of your app. This initial instance includes a debugger that interferes with Crashlytics.
  3. Open your app again from the simulator or device.
  4. Touch Crash to crash the app.
  5. Open your app once more to let the Crashlytics API report the crash. Your crash should show up in the Firebase console within 5 minutes.

Firebase Remote Config allows you to remotely configure your active clients. FriendlyChat messages are restricted to a maximum length. While this length can be defined directly in the client, defining this maximum length with Firebase Remote Config allows an update to the maximum length to be applied to active clients.

Add Config Rules in Firebase console

In Firebase console, select the "Remote Config" panel and click "Add your first parameter". Set the parameter key to friendly_msg_length and the parameter value to 10. Select Publish Changes to apply the updates.

Confirm Firebase RemoteConfig dependency

Confirm the pod 'Firebase/RemoteConfig' dependency exists in your Podfile file.

Configure Firebase Remote Config

FCViewController.m

- (void)configureRemoteConfig {
  _remoteConfig = [FIRRemoteConfig remoteConfig];
  // Create Remote Config Setting to enable developer mode.
  // Fetching configs from the server is normally limited to 5 requests per hour.
  // Enabling developer mode allows many more requests to be made per hour, so developers
  // can test different config values during development.
  FIRRemoteConfigSettings *remoteConfigSettings = [[FIRRemoteConfigSettings alloc] initWithDeveloperModeEnabled:YES];
  self.remoteConfig.configSettings = remoteConfigSettings;
}

Request and Use Config

Create a fetch request for config and add a completion handler to pick up and use the config parameters.

FCViewController.m

- (void)fetchConfig {
  long expirationDuration = 3600;
  // If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
  // the server.
  if (self.remoteConfig.configSettings.isDeveloperModeEnabled) {
    expirationDuration = 0;
  }

  // cacheExpirationSeconds is set to cacheExpiration here, indicating that any previously
  // fetched and cached config would be considered expired because it would have been fetched
  // more than cacheExpiration seconds ago. Thus the next fetch would go to the server unless
  // throttling is in progress. The default expiration duration is 43200 (12 hours).
  [self.remoteConfig fetchWithExpirationDuration:expirationDuration completionHandler:^(FIRRemoteConfigFetchStatus status, NSError *error) {
    if (status == FIRRemoteConfigFetchStatusSuccess) {
      NSLog(@"Config fetched!");
      [_remoteConfig activateFetched];
      FIRRemoteConfigValue *friendlyMsgLength = _remoteConfig[@"friendly_msg_length"];
      if (friendlyMsgLength.source != FIRRemoteConfigSourceStatic) {
        _msglength = friendlyMsgLength.numberValue.intValue;
        NSLog(@"Friendly msg length config: %d", _msglength);
      }
    } else {
      NSLog(@"Config not fetched");
      NSLog(@"Error %@", error);
    }
  }];
}

Test Remote Config

  1. Click the Run button.
  2. Check that the Friendly Message character limit has been set to 10 by trying to send a message longer than 10 characters (extra characters will be truncated.). Update the Remote Config value from 10 to 30, then select Update then Publish Changes. From the navigation bar tap fresh config (in the upper right) and confirm that the Friendly Message character limit is now 30.

Firebase A/B Testing helps you optimize your app experience by making it easy to run, analyze, and scale product and marketing experiments. Here you will use Firebase A/B testing to try different message lengths.

Get your app's Instance ID

Click the Run button. Then search for the line with "Remote instance ID token" in the Xcode console. Make note of the token.

Create experiment

  1. From the Firebase console, select `A/B Testing` from the navigation panel. Select `create experiment`.
  2. Choose Remote Config as the type of experiment to create.
  3. Name your experiment "max msg length" and set the description to "What is the best max msg length". Select `Next`.
  4. Select the Friendly Chat app as the target. Select `Next`.
  5. Select primary metric to track. Choose the `message` event if available or `first_open` otherwise. It may take a few hours before the `message` event is available here so use `first_open` for now. Select `Next`.
  6. For the control group select `friendly_msg_length` parameter. For Variant B set the value to 10. Select `Add another variant` and set its value to 3. Select `Save`.
  7. Expand your draft experiment and select `Manage test devices`.
  8. Paste in your Instance ID token and select Variant A for testing. Select `Add` and `Save`.
  9. Now hit `Fetch Config` in your app's UI and verify that your text field is limited to the Variant A value.

You have used Firebase to take Friendly Chat to the next level.

What we've covered

Next Steps

Learn More