> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# v3-4 SDK Email SDK Methods

> How to set up email messaging on your app or website

<Warning>
  The methods below require the OneSignal SDK versions 3 & 4.

  It is recommended to upgrade to our latest version 5 SDKs for User Model APIs.

  See [Update to User Model](/docs/en/user-model-migration-guide) for migration steps.
</Warning>

If you have not done so, we always recommend updating the OneSignal SDK to the latest version to get access to the latest features:

* [Web Push Quickstart](/docs/en/web-push-setup)
* [Mobile Push Quickstart](/docs/en/mobile-sdk-setup)

<Warning>
  Email and Push subscribers will have separate OneSignal Subscription IDs (user records). This is to manage the case where a user opts-out of one you can still send messages to the other. Email records cannot get push notifications and push records cannot get emails.
</Warning>

<Warning>
  If there are networking issues, functions may take 30+ seconds to return. In the code examples below we provide callbacks to track when these return.

  Make sure to keep functions from blocking the user interface, otherwise your app may appear unresponsive to the user.
</Warning>

# Setting the Users Email

## `setEmail` Method

Allows you to set the user's email address with the OneSignal SDK. We offer several overloaded versions of this method.

It is best to call this when the user provides their email. If `setEmail` called previously and the user changes their email, calling`setEmail` again will update that record with the new email address.

<CodeGroup>
  ```javascript Web (js) theme={null}
  OneSignal.push(function() {
    OneSignal.setEmail("[email protected]")          
      .then(function(emailId) {
        // Callback called when email have finished sending
        console.log("emailId: ", emailId);  
      }); 
  });
  ```

  ```java Java theme={null}
  OneSignal.setEmail("[email protected]", null, new OneSignal.EmailUpdateHandler() {
     @Override
     public void onSuccess() {
        OneSignal.onesignalLog(OneSignal.LOG_LEVEL.VERBOSE, "SetEmail Successful");
     }
     @Override
     public void onFailure(OneSignal.EmailUpdateError error) {
        OneSignal.onesignalLog(OneSignal.LOG_LEVEL.VERBOSE, "SetEmail Failed with error: " + error.toString());
     }
  });
  ```

  ```swift Swift theme={null}
  OneSignal.setEmail("[email protected]", withSuccess: {
    print("email set successfully")
  }, withFailure: {error in
    print("os setEmail error: \(error!.localizedDescription)")
  })
  ```

  ```objectivec Objective-C theme={null}
  [OneSignal setEmail:@"[email protected]"];
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.SetEmail("[email protected]");

  var result = await OneSignal.Default.SetEmail("[email protected]");
  if (result) {
      Debug.Log("success");
  }
  else {
      Debug.Log("error");
  }
  ```

  ```javascript React Native theme={null}
  OneSignal.setEmail("[email protected]");
  ```

  ```javascript Flutter theme={null}
  OneSignal.shared.setEmail(email: "[email protected]").whenComplete(() {
    print("Successfully set email");
  }).catchError((error) {
    print("Failed to set email with error: $error");
  });
  ```

  ```javascript Cordova/Ionic theme={null}
  // Ionic 5 Capacitor may need to use (window as any).plugins.OneSignal
  window.plugins.OneSignal.setEmail("[email protected]");
  ```

  ```csharp Xamarin theme={null}
  OneSignal.Current.SetEmail("[email protected]");
  ```
</CodeGroup>

If you have a backend server, we strongly recommend using [Identity Verification](/v9.0/docs/identity-verification) with your users. Your backend can generate an ***email authentication token*** and send it to your app or website.

<Warning>
  **Recommendation**: call [`setExternalUserId`](/docs/en/users) again within the `setEmail` callback to link the records together.
</Warning>

# Logout Email

## `logoutEmail` Method

If your app or website implements logout functionality, you can call `logoutEmail` to dissociate the email from the device:

<CodeGroup>
  ```javascript Web (js) theme={null}
  OneSignal.push(function() {
    OneSignal.logoutEmail();
  });
  ```

  ```java Java theme={null}
  OneSignal.logoutEmail();
  ```

  ```swift Swift theme={null}
  OneSignal.logoutEmail();
  ```

  ```objectivec objectivec theme={null}
  [OneSignal logoutEmail]
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.LogoutEmail();

  var result = await OneSignal.Default.LogoutEmail();
  if (result) {
      Debug.Log("success");
  }
  else {
      Debug.Log("error");
  }
  ```

  ```javascript React Native theme={null}
  OneSignal.logoutEmail(function(successResponse) {
      //Successfully logged out of email
  }, function(error) {
      //Failed to log out of email
  });
  ```

  ```javascript Flutter theme={null}
  await OneSignal.shared.logoutEmail();
  ```

  ```javascript Cordova/Ionic theme={null}
  // Ionic 5 Capacitor may need to use (window as any).plugins.OneSignal
  window.plugins.OneSignal.logoutEmail(function(successResponse) {
      //Successfully logged out of email
  }, function(error) {
      //Failed to log out of email
  });
  ```

  ```csharp Xamarin theme={null}
  OneSignal.Current.LogoutEmail();

  // Optionally, you can also use callbacks
  OneSignal.Current.LogoutEmail(() => {
    //handle success
  }, (error) => {
    //handle failure
  });
  ```
</CodeGroup>

# Listening for subscription changes

Tracks changes to email subscriptions (for example, if the user sets their email, or logs out). In order to subscribe to email subscription changes, you can implement the following:

| Event Object Property | Type     |
| --------------------- | -------- |
| `email`               | `string` |

<CodeGroup>
  ```java Java theme={null}
  OneSignal.addEmailSubscriptionObserver(subscriptionObserver);

  //Now, whenever the email subscription changes, this method will be called:

  OSEmailSubscriptionObserver subscriptionObserver = new OSEmailSubscriptionObserver() {
     @Override
     public void onOSEmailSubscriptionChanged(OSEmailSubscriptionStateChanges stateChanges) {
     }
  };
  ```

  ```swift Swift theme={null}
  OneSignal.add(self as OSEmailSubscriptionObserver)

  //Now, whenever the email subscription changes, this method will be called:

  func onOSEmailSubscriptionChanged(_ stateChanges: OSEmailSubscriptionStateChanges!) { 
      
  }
  ```

  ```objectivec objectivec theme={null}
  [OneSignal addEmailSubscriptionObserver:self];

  //Now, whenever the email subscription changes, this method will be called:

  -(void)onOSEmailSubscriptionChanged:(OSEmailSubscriptionStateChanges *)stateChanges {
      
  }
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.EmailSubscriptionStateChanged += (current, previous) => {
      var emailSubscribed = current.isSubscribed;
  };
  ```

  ```javascript React Native theme={null}
  // Requires React Native SDK 4.x
  OneSignal.addEmailSubscriptionObserver((event) => {
      console.log("OneSignal: email subscription changed: ", event);
  });
  ```

  ```javascript Flutter theme={null}
  //Requires Flutter SDK 3.x
  OneSignal.shared.setEmailSubscriptionObserver(
          (OSEmailSubscriptionStateChanges changes) {
        print("OneSignal: email subscription changed: ${changes.jsonRepresentation()}");
  });
  ```

  ```javascript Cordova/Ionic theme={null}
  // Ionic 5 Capacitor may need to use (window as any).plugins.OneSignal
  window.plugins.OneSignal.addEmailSubscriptionObserver(function(stateChanges) {
      //Email subscription state changed
      let newEmailAddress = stateChanges.to.emailAddress;
      let newUserId = stateChanges.to.emailUserId;
  });
  ```

  ```csharp Xamarin theme={null}
  //Currently not available
  ```

  ```csharp Unity(C#) theme={null}
  OneSignal.Default.EmailSubscriptionStateChanged += (current, previous) => {
      var emailSubscribed = current.isSubscribed;
  };
  ```

  ```javascript javascript theme={null}
  OneSignal.on("emailSubscriptionChanged", event => {
     const { email } = event;
     console.log("email: ", email);
  });
  ```
</CodeGroup>

## `getEmailId` Method

**Web only** - Returns a `Promise` that resolves to the stored OneSignal Subscription ID of the Email Record if one is set using the `setEmail` method. Otherwise the Promise resolves to `null`. If the user isn't already subscribed, this function will resolve to `null` immediately.

Once created, the Email Record Subscription ID will not change. If the user unsubscribes from web push, for example by clearing their browser data, you should call `setEmail` with the same email as before to maintain the same Email Record Subscription ID and tie it to the new Push Subscription ID.

Callback function sets the first parameter to the stored Email Record's OneSignal Subscription ID if one is set, otherwise the first parameter is set to null.

<CodeGroup>
  ```javascript Web (js) theme={null}
  OneSignal.push(function() {
    OneSignal.getEmailId(function(emailId) {
      console.log("OneSignal Email ID:", emailId);
      // (Output) OneSignal Email ID: 270a35cd-4dda-4b3f-b04e-41d7463a2316    
    });
  });
  // Both examples are valid
  OneSignal.push(function() {
    OneSignal.getEmailId().then(function(emailId) {
      console.log("OneSignal Email ID:", emailId);
      // (Output) OneSignal Email ID: 270a35cd-4dda-4b3f-b04e-41d7463a2316    
    });
  });
  ```

  ```csharp Unity(C#) theme={null}
  var emailState = OneSignal.Default.EmailSubscriptionState;
  var emailUserId  = emailState.emailUserId;
  var emailAddress = emailState.emailAddress;
  ```
</CodeGroup>

***
