diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js
index 11dba205547c3ee1828a290739966f20610c34f7..5b3a59a3420fce62701a234353a72c3f685c6642 100644
--- a/app/containers/message/Markdown.js
+++ b/app/containers/message/Markdown.js
@@ -14,98 +14,90 @@ const formatText = text => text.replace(
 	(match, url, title) => `[${ title }](${ url })`
 );
 
-export default class Markdown extends React.Component {
-	shouldComponentUpdate(nextProps) {
-		const { msg } = this.props;
-		return nextProps.msg !== msg;
+const Markdown = React.memo(({
+	msg, customEmojis, style, rules, baseUrl, username, edited, numberOfLines
+}) => {
+	if (!msg) {
+		return null;
 	}
-
-	render() {
-		const {
-			msg, customEmojis, style, rules, baseUrl, username, edited, numberOfLines
-		} = this.props;
-		if (!msg) {
-			return null;
-		}
-		let m = formatText(msg);
-		if (m) {
-			m = emojify(m, { output: 'unicode' });
-		}
-		m = m.replace(/^\[([^\]]*)\]\(([^)]*)\)/, '').trim();
-		if (numberOfLines > 0) {
-			m = m.replace(/[\n]+/g, '\n').trim();
-		}
-		return (
-			<MarkdownRenderer
-				rules={{
-					paragraph: (node, children) => (
-						// eslint-disable-next-line
-						<Text key={node.key} style={styles.paragraph} numberOfLines={numberOfLines}>
-							{children}
-							{edited ? <Text style={styles.edited}> (edited)</Text> : null}
-						</Text>
-					),
-					mention: (node) => {
-						const { content, key } = node;
-						let mentionStyle = styles.mention;
-						if (content === 'all' || content === 'here') {
-							mentionStyle = {
-								...mentionStyle,
-								...styles.mentionAll
-							};
-						} else if (content === username) {
-							mentionStyle = {
-								...mentionStyle,
-								...styles.mentionLoggedUser
-							};
-						}
-						return (
-							<Text style={mentionStyle} key={key}>
-								&nbsp;{content}&nbsp;
-							</Text>
-						);
-					},
-					hashtag: node => (
-						<Text key={node.key} style={styles.mention}>
-							&nbsp;#{node.content}&nbsp;
+	let m = formatText(msg);
+	if (m) {
+		m = emojify(m, { output: 'unicode' });
+	}
+	m = m.replace(/^\[([^\]]*)\]\(([^)]*)\)/, '').trim();
+	if (numberOfLines > 0) {
+		m = m.replace(/[\n]+/g, '\n').trim();
+	}
+	return (
+		<MarkdownRenderer
+			rules={{
+				paragraph: (node, children) => (
+					// eslint-disable-next-line
+					<Text key={node.key} style={styles.paragraph} numberOfLines={numberOfLines}>
+						{children}
+						{edited ? <Text style={styles.edited}> (edited)</Text> : null}
+					</Text>
+				),
+				mention: (node) => {
+					const { content, key } = node;
+					let mentionStyle = styles.mention;
+					if (content === 'all' || content === 'here') {
+						mentionStyle = {
+							...mentionStyle,
+							...styles.mentionAll
+						};
+					} else if (content === username) {
+						mentionStyle = {
+							...mentionStyle,
+							...styles.mentionLoggedUser
+						};
+					}
+					return (
+						<Text style={mentionStyle} key={key}>
+							&nbsp;{content}&nbsp;
 						</Text>
-					),
-					emoji: (node) => {
-						if (node.children && node.children.length && node.children[0].content) {
-							const { content } = node.children[0];
-							const emojiExtension = customEmojis[content];
-							if (emojiExtension) {
-								const emoji = { extension: emojiExtension, content };
-								return <CustomEmoji key={node.key} baseUrl={baseUrl} style={styles.customEmoji} emoji={emoji} />;
-							}
-							return <Text key={node.key}>:{content}:</Text>;
+					);
+				},
+				hashtag: node => (
+					<Text key={node.key} style={styles.mention}>
+						&nbsp;#{node.content}&nbsp;
+					</Text>
+				),
+				emoji: (node) => {
+					if (node.children && node.children.length && node.children[0].content) {
+						const { content } = node.children[0];
+						const emojiExtension = customEmojis[content];
+						if (emojiExtension) {
+							const emoji = { extension: emojiExtension, content };
+							return <CustomEmoji key={node.key} baseUrl={baseUrl} style={styles.customEmoji} emoji={emoji} />;
 						}
-						return null;
-					},
-					hardbreak: () => null,
-					blocklink: () => null,
-					image: node => (
-						<Image key={node.key} style={styles.inlineImage} source={{ uri: node.attributes.src }} />
-					),
-					...rules
-				}}
-				style={{
-					paragraph: styles.paragraph,
-					text: styles.text,
-					codeInline: styles.codeInline,
-					codeBlock: styles.codeBlock,
-					link: styles.link,
-					...style
-				}}
-				plugins={[
-					new PluginContainer(MarkdownFlowdock),
-					new PluginContainer(MarkdownEmojiPlugin)
-				]}
-			>{m}
-			</MarkdownRenderer>
-		);
-	}
-}
+						return <Text key={node.key}>:{content}:</Text>;
+					}
+					return null;
+				},
+				hardbreak: () => null,
+				blocklink: () => null,
+				image: node => (
+					<Image key={node.key} style={styles.inlineImage} source={{ uri: node.attributes.src }} />
+				),
+				...rules
+			}}
+			style={{
+				paragraph: styles.paragraph,
+				text: styles.text,
+				codeInline: styles.codeInline,
+				codeBlock: styles.codeBlock,
+				link: styles.link,
+				...style
+			}}
+			plugins={[
+				new PluginContainer(MarkdownFlowdock),
+				new PluginContainer(MarkdownEmojiPlugin)
+			]}
+		>{m}
+		</MarkdownRenderer>
+	);
+}, (prevProps, nextProps) => prevProps.msg === nextProps.msg);
 
 Markdown.propTypes = {
 	msg: PropTypes.string,
@@ -117,3 +109,5 @@ Markdown.propTypes = {
 	edited: PropTypes.bool,
 	numberOfLines: PropTypes.number
 };
+
+export default Markdown;
diff --git a/app/lib/methods/getCustomEmojis.js b/app/lib/methods/getCustomEmojis.js
index adcb2e83c6419a8da5e3de50fc6a4029e4178989..207ef446cc398a1b984e0701d30ba6cf22b837fe 100644
--- a/app/lib/methods/getCustomEmojis.js
+++ b/app/lib/methods/getCustomEmojis.js
@@ -1,39 +1,83 @@
 import { InteractionManager } from 'react-native';
+import semver from 'semver';
 
 import reduxStore from '../createStore';
 import database from '../realm';
 import * as actions from '../../actions';
 import log from '../../utils/log';
 
-const getLastMessage = () => {
-	const setting = database.objects('customEmojis').sorted('_updatedAt', true)[0];
-	return setting && setting._updatedAt;
+const getUpdatedSince = () => {
+	const emoji = database.objects('customEmojis').sorted('_updatedAt', true)[0];
+	return emoji && emoji._updatedAt.toISOString();
 };
 
-// TODO: fix api (get emojis by date/version....)
+const create = (customEmojis) => {
+	if (customEmojis && customEmojis.length) {
+		customEmojis.forEach((emoji) => {
+			try {
+				database.create('customEmojis', emoji, true);
+			} catch (e) {
+				log('getEmojis create', e);
+			}
+		});
+	}
+};
+
+
 export default async function() {
 	try {
-		const lastMessage = getLastMessage();
-		// RC 0.61.0
-		const result = await this.sdk.get('emoji-custom');
-		let { emojis } = result;
-		emojis = emojis.filter(emoji => !lastMessage || emoji._updatedAt > lastMessage);
-		if (emojis.length === 0) {
-			return;
-		}
-		emojis = this._prepareEmojis(emojis);
-		InteractionManager.runAfterInteractions(() => {
-			database.write(() => {
-				emojis.forEach((emoji) => {
-					try {
-						database.create('customEmojis', emoji, true);
-					} catch (e) {
-						log('create custom emojis', e);
-					}
+		const serverVersion = reduxStore.getState().server.version;
+		const updatedSince = getUpdatedSince();
+
+		// if server version is lower than 0.75.0, fetches from old api
+		if (semver.lt(serverVersion, '0.75.0')) {
+			// RC 0.61.0
+			const result = await this.sdk.get('emoji-custom');
+
+			InteractionManager.runAfterInteractions(() => {
+				let { emojis } = result;
+				emojis = emojis.filter(emoji => !updatedSince || emoji._updatedAt > updatedSince);
+				database.write(() => {
+					create(emojis);
 				});
+				reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(result.emojis)));
 			});
-		});
-		reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(emojis)));
+		} else {
+			const params = {};
+			if (updatedSince) {
+				params.updatedSince = updatedSince;
+			}
+
+			// RC 0.75.0
+			const result = await this.sdk.get('emoji-custom.list', params);
+
+			if (!result.success) {
+				return;
+			}
+
+			InteractionManager.runAfterInteractions(
+				() => database.write(() => {
+					const { emojis } = result;
+					create(emojis.update);
+
+					if (emojis.delete && emojis.delete.length) {
+						emojis.delete.forEach((emoji) => {
+							try {
+								const emojiRecord = database.objectForPrimaryKey('customEmojis', emoji._id);
+								if (emojiRecord) {
+									database.delete(emojiRecord);
+								}
+							} catch (e) {
+								log('getEmojis delete', e);
+							}
+						});
+					}
+
+					const allEmojis = database.objects('customEmojis');
+					reduxStore.dispatch(actions.setCustomEmojis(this.parseEmojis(allEmojis)));
+				})
+			);
+		}
 	} catch (e) {
 		log('getCustomEmojis', e);
 	}
diff --git a/app/lib/methods/helpers/mergeSubscriptionsRooms.js b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
index c09caed51302252a9245ad86e9aeeaaf9eeafbcf..7983cac0819f8ab51d187f7936ed3535ab2a6028 100644
--- a/app/lib/methods/helpers/mergeSubscriptionsRooms.js
+++ b/app/lib/methods/helpers/mergeSubscriptionsRooms.js
@@ -24,6 +24,9 @@ export const merge = (subscription, room) => {
 		subscription.archived = room.archived;
 		subscription.joinCodeRequired = room.joinCodeRequired;
 		subscription.broadcast = room.broadcast;
+		if (!subscription.roles || !subscription.roles.length) {
+			subscription.roles = [];
+		}
 
 		if (room.muted && room.muted.length) {
 			subscription.muted = room.muted.filter(user => user).map(user => ({ value: user }));
diff --git a/app/lib/realm.js b/app/lib/realm.js
index 8c2bbc54747cf60bfed253215a49665ff76b2be1..a36327349ffbf9bb127444ccb7fe55bb4d52d528 100644
--- a/app/lib/realm.js
+++ b/app/lib/realm.js
@@ -286,21 +286,13 @@ const frequentlyUsedEmojiSchema = {
 	}
 };
 
-const customEmojiAliasesSchema = {
-	name: 'customEmojiAliases',
-	primaryKey: 'value',
-	properties: {
-		value: 'string'
-	}
-};
-
 const customEmojisSchema = {
 	name: 'customEmojis',
 	primaryKey: '_id',
 	properties: {
 		_id: 'string',
 		name: 'string',
-		aliases: { type: 'list', objectType: 'customEmojiAliases' },
+		aliases: 'string[]',
 		extension: 'string',
 		_updatedAt: { type: 'date', optional: true }
 	}
@@ -353,7 +345,6 @@ const schema = [
 	permissionsSchema,
 	url,
 	frequentlyUsedEmojiSchema,
-	customEmojiAliasesSchema,
 	customEmojisSchema,
 	messagesReactionsSchema,
 	messagesReactionsUsernamesSchema,
@@ -428,7 +419,7 @@ class DB {
 		return this.databases.activeDB = new Realm({
 			path: `${ path }.realm`,
 			schema,
-			schemaVersion: 8,
+			schemaVersion: 9,
 			migration: (oldRealm, newRealm) => {
 				if (oldRealm.schemaVersion >= 3 && newRealm.schemaVersion <= 8) {
 					const newSubs = newRealm.objects('subscriptions');
@@ -445,6 +436,14 @@ class DB {
 					const newThreadMessages = newRealm.objects('threadMessages');
 					newRealm.delete(newThreadMessages);
 				}
+				if (newRealm.schemaVersion === 9) {
+					const newSubs = newRealm.objects('subscriptions');
+					newRealm.delete(newSubs);
+					const newEmojis = newRealm.objects('customEmojis');
+					newRealm.delete(newEmojis);
+					const newSettings = newRealm.objects('settings');
+					newRealm.delete(newSettings);
+				}
 			}
 		});
 	}