mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-23 12:06:47 +08:00
[invites] Initial JS and Android invites functionality
This commit is contained in:
@@ -19,6 +19,7 @@ import Crashlytics, {
|
||||
import Database, { NAMESPACE as DatabaseNamespace } from '../database';
|
||||
import Firestore, { NAMESPACE as FirestoreNamespace } from '../firestore';
|
||||
import InstanceId, { NAMESPACE as InstanceIdNamespace } from '../instanceid';
|
||||
import Invites, { NAMESPACE as InvitesNamespace } from '../invites';
|
||||
import Links, { NAMESPACE as LinksNamespace } from '../links';
|
||||
import Messaging, { NAMESPACE as MessagingNamespace } from '../messaging';
|
||||
import Notifications, {
|
||||
@@ -49,6 +50,7 @@ export default class App {
|
||||
};
|
||||
firestore: () => Firestore;
|
||||
instanceid: () => InstanceId;
|
||||
invites: () => Invites;
|
||||
links: () => Links;
|
||||
messaging: () => Messaging;
|
||||
notifications: () => Notifications;
|
||||
@@ -90,6 +92,7 @@ export default class App {
|
||||
};
|
||||
this.firestore = APPS.appModule(this, FirestoreNamespace, Firestore);
|
||||
this.instanceid = APPS.appModule(this, InstanceIdNamespace, InstanceId);
|
||||
this.invites = APPS.appModule(this, InvitesNamespace, Invites);
|
||||
this.links = APPS.appModule(this, LinksNamespace, Links);
|
||||
this.messaging = APPS.appModule(this, MessagingNamespace, Messaging);
|
||||
this.notifications = APPS.appModule(
|
||||
|
||||
@@ -42,6 +42,10 @@ import {
|
||||
statics as InstanceIdStatics,
|
||||
MODULE_NAME as InstanceIdModuleName,
|
||||
} from '../instanceid';
|
||||
import {
|
||||
statics as InvitesStatics,
|
||||
MODULE_NAME as InvitesModuleName,
|
||||
} from '../invites';
|
||||
import {
|
||||
statics as LinksStatics,
|
||||
MODULE_NAME as LinksModuleName,
|
||||
@@ -78,6 +82,7 @@ import type {
|
||||
FirebaseOptions,
|
||||
FirestoreModule,
|
||||
InstanceIdModule,
|
||||
InvitesModule,
|
||||
LinksModule,
|
||||
MessagingModule,
|
||||
NotificationsModule,
|
||||
@@ -98,6 +103,7 @@ class Firebase {
|
||||
fabric: FabricModule;
|
||||
firestore: FirestoreModule;
|
||||
instanceid: InstanceIdModule;
|
||||
invites: InvitesModule;
|
||||
links: LinksModule;
|
||||
messaging: MessagingModule;
|
||||
notifications: NotificationsModule;
|
||||
@@ -147,6 +153,11 @@ class Firebase {
|
||||
InstanceIdStatics,
|
||||
InstanceIdModuleName
|
||||
);
|
||||
this.invites = APPS.moduleAndStatics(
|
||||
'invites',
|
||||
InvitesStatics,
|
||||
InvitesModuleName
|
||||
);
|
||||
this.links = APPS.moduleAndStatics('links', LinksStatics, LinksModuleName);
|
||||
this.messaging = APPS.moduleAndStatics(
|
||||
'messaging',
|
||||
|
||||
69
lib/modules/invites/AndroidInvitation.js
Normal file
69
lib/modules/invites/AndroidInvitation.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @flow
|
||||
* AndroidInvitation representation wrapper
|
||||
*/
|
||||
import type Invitation from './Invitation';
|
||||
import type { NativeAndroidInvitation } from './types';
|
||||
|
||||
export default class AndroidInvitation {
|
||||
_additionalReferralParameters: { [string]: string } | void;
|
||||
_emailHtmlContent: string | void;
|
||||
_emailSubject: string | void;
|
||||
_googleAnalyticsTrackingId: string | void;
|
||||
_invitation: Invitation;
|
||||
|
||||
constructor(invitation: Invitation) {
|
||||
this._invitation = invitation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param additionalReferralParameters
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setAdditionalReferralParameters(additionalReferralParameters: {
|
||||
[string]: string,
|
||||
}): Invitation {
|
||||
this._additionalReferralParameters = additionalReferralParameters;
|
||||
return this._invitation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param emailHtmlContent
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setEmailHtmlContent(emailHtmlContent: string): Invitation {
|
||||
this._emailHtmlContent = emailHtmlContent;
|
||||
return this._invitation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param emailSubject
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setEmailSubject(emailSubject: string): Invitation {
|
||||
this._emailSubject = emailSubject;
|
||||
return this._invitation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param googleAnalyticsTrackingId
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setGoogleAnalyticsTrackingId(googleAnalyticsTrackingId: string): Invitation {
|
||||
this._googleAnalyticsTrackingId = googleAnalyticsTrackingId;
|
||||
return this._invitation;
|
||||
}
|
||||
|
||||
build(): NativeAndroidInvitation {
|
||||
return {
|
||||
additionalReferralParameters: this._additionalReferralParameters,
|
||||
emailHtmlContent: this._emailHtmlContent,
|
||||
emailSubject: this._emailSubject,
|
||||
googleAnalyticsTrackingId: this._googleAnalyticsTrackingId,
|
||||
};
|
||||
}
|
||||
}
|
||||
106
lib/modules/invites/Invitation.js
Normal file
106
lib/modules/invites/Invitation.js
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @flow
|
||||
* Invitation representation wrapper
|
||||
*/
|
||||
import { Platform } from 'react-native';
|
||||
import AndroidInvitation from './AndroidInvitation';
|
||||
|
||||
import type { NativeInvitation } from './types';
|
||||
|
||||
export default class Invitation {
|
||||
_android: AndroidInvitation;
|
||||
_androidClientId: string | void;
|
||||
_androidMinimumVersionCode: number | void;
|
||||
_callToActionText: string | void;
|
||||
_customImage: string | void;
|
||||
_deepLink: string | void;
|
||||
_iosClientId: string | void;
|
||||
_message: string;
|
||||
_title: string;
|
||||
|
||||
constructor(title: string, message: string) {
|
||||
this._android = new AndroidInvitation(this);
|
||||
this._message = message;
|
||||
this._title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param androidClientId
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setAndroidClientId(androidClientId: string): Invitation {
|
||||
this._androidClientId = androidClientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param androidMinimumVersionCode
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setAndroidMinimumVersionCode(androidMinimumVersionCode: number): Invitation {
|
||||
this._androidMinimumVersionCode = androidMinimumVersionCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param callToActionText
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setCallToActionText(callToActionText: string): Invitation {
|
||||
this._callToActionText = callToActionText;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param customImage
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setCustomImage(customImage: string): Invitation {
|
||||
this._customImage = customImage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param deepLink
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setDeepLink(deepLink: string): Invitation {
|
||||
this._deepLink = deepLink;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param iosClientId
|
||||
* @returns {Invitation}
|
||||
*/
|
||||
setIOSClientId(iosClientId: string): Invitation {
|
||||
this._iosClientId = iosClientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): NativeInvitation {
|
||||
if (!this._message) {
|
||||
throw new Error('Invitation: Missing required `message` property');
|
||||
} else if (!this._title) {
|
||||
throw new Error('Invitation: Missing required `title` property');
|
||||
}
|
||||
|
||||
return {
|
||||
android: Platform.OS === 'android' ? this._android.build() : undefined,
|
||||
androidClientId: this._androidClientId,
|
||||
androidMinimumVersionCode: this._androidMinimumVersionCode,
|
||||
callToActionText: this._callToActionText,
|
||||
customImage: this._customImage,
|
||||
deepLink: this._deepLink,
|
||||
iosClientId: this._iosClientId,
|
||||
message: this._message,
|
||||
title: this._title,
|
||||
};
|
||||
}
|
||||
}
|
||||
77
lib/modules/invites/index.js
Normal file
77
lib/modules/invites/index.js
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @flow
|
||||
* Invites representation wrapper
|
||||
*/
|
||||
import { SharedEventEmitter } from '../../utils/events';
|
||||
import { getLogger } from '../../utils/log';
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
import Invitation from './Invitation';
|
||||
|
||||
import type App from '../core/app';
|
||||
|
||||
export const MODULE_NAME = 'RNFirebaseInvites';
|
||||
export const NAMESPACE = 'invites';
|
||||
const NATIVE_EVENTS = ['invites_invitation_received'];
|
||||
|
||||
type InvitationOpen = {
|
||||
deepLink: string,
|
||||
invitationId: string,
|
||||
};
|
||||
|
||||
export default class Invites extends ModuleBase {
|
||||
constructor(app: App) {
|
||||
super(app, {
|
||||
events: NATIVE_EVENTS,
|
||||
moduleName: MODULE_NAME,
|
||||
multiApp: false,
|
||||
namespace: NAMESPACE,
|
||||
});
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'invites_invitation_received',
|
||||
(invitation: InvitationOpen) => {
|
||||
SharedEventEmitter.emit('onInvitation', invitation);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invitation that triggered application open
|
||||
* @returns {Promise.<Object>}
|
||||
*/
|
||||
getInitialInvitation(): Promise<string> {
|
||||
return getNativeModule(this).getInitialInvitation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to invites
|
||||
* @param listener
|
||||
* @returns {Function}
|
||||
*/
|
||||
onInvitation(listener: InvitationOpen => any) {
|
||||
getLogger(this).info('Creating onInvitation listener');
|
||||
|
||||
SharedEventEmitter.addListener('onInvitation', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onInvitation listener');
|
||||
SharedEventEmitter.removeListener('onInvitation', listener);
|
||||
};
|
||||
}
|
||||
|
||||
sendInvitation(invitation: Invitation): Promise<string[]> {
|
||||
if (!(invitation instanceof Invitation)) {
|
||||
throw new Error(
|
||||
`Invites:sendInvitation expects an 'Invitation' but got type ${typeof invitation}`
|
||||
);
|
||||
}
|
||||
return getNativeModule(this).sendInvitation(invitation.build());
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
Invitation,
|
||||
};
|
||||
21
lib/modules/invites/types.js
Normal file
21
lib/modules/invites/types.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
export type NativeAndroidInvitation = {|
|
||||
additionalReferralParameters?: { [string]: string },
|
||||
emailHtmlContent?: string,
|
||||
emailSubject?: string,
|
||||
googleAnalyticsTrackingId?: string,
|
||||
|};
|
||||
|
||||
export type NativeInvitation = {|
|
||||
android?: NativeAndroidInvitation,
|
||||
androidClientId?: string,
|
||||
androidMinimumVersionCode?: number,
|
||||
callToActionText?: string,
|
||||
customImage?: string,
|
||||
deepLink?: string,
|
||||
iosClientId?: string,
|
||||
message: string,
|
||||
title: string,
|
||||
|};
|
||||
@@ -3,6 +3,7 @@
|
||||
* Dynamic Links representation wrapper
|
||||
*/
|
||||
import { SharedEventEmitter } from '../../utils/events';
|
||||
import { getLogger } from '../../utils/log';
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import { areObjectKeysContainedInOther, isObject, isString } from '../../utils';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
@@ -10,7 +11,7 @@ import { getNativeModule } from '../../utils/native';
|
||||
import type App from '../core/app';
|
||||
|
||||
const EVENT_TYPE = {
|
||||
Link: 'dynamic_link_received',
|
||||
Link: 'links_link_received',
|
||||
};
|
||||
|
||||
const NATIVE_EVENTS = [EVENT_TYPE.Link];
|
||||
@@ -82,33 +83,21 @@ export default class Links extends ModuleBase {
|
||||
multiApp: false,
|
||||
namespace: NAMESPACE,
|
||||
});
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'links_link_received',
|
||||
(link: string) => {
|
||||
SharedEventEmitter.emit('onLink', link);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get EVENT_TYPE(): Object {
|
||||
return EVENT_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link that triggered application open
|
||||
* @returns {Promise.<String>}
|
||||
*/
|
||||
getInitialLink(): Promise<string> {
|
||||
return getNativeModule(this).getInitialLink();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to dynamic links
|
||||
* @param listener
|
||||
* @returns {Function}
|
||||
*/
|
||||
onLink(listener: Function): () => any {
|
||||
const rnListener = SharedEventEmitter.addListener(
|
||||
EVENT_TYPE.Link,
|
||||
listener
|
||||
);
|
||||
return () => rnListener.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create long Dynamic Link from parameters
|
||||
* @param parameters
|
||||
@@ -138,6 +127,30 @@ export default class Links extends ModuleBase {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the link that triggered application open
|
||||
* @returns {Promise.<String>}
|
||||
*/
|
||||
getInitialLink(): Promise<string> {
|
||||
return getNativeModule(this).getInitialLink();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to dynamic links
|
||||
* @param listener
|
||||
* @returns {Function}
|
||||
*/
|
||||
onLink(listener: string => any): () => any {
|
||||
getLogger(this).info('Creating onLink listener');
|
||||
|
||||
SharedEventEmitter.addListener('onLink', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onLink listener');
|
||||
SharedEventEmitter.removeListener('onLink', listener);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
|
||||
@@ -133,13 +133,13 @@ export default class RemoteMessage {
|
||||
}
|
||||
|
||||
build(): NativeOutboundRemoteMessage {
|
||||
if (!this.data) {
|
||||
if (!this._data) {
|
||||
throw new Error('RemoteMessage: Missing required `data` property');
|
||||
} else if (!this.messageId) {
|
||||
} else if (!this._messageId) {
|
||||
throw new Error('RemoteMessage: Missing required `messageId` property');
|
||||
} else if (!this.to) {
|
||||
} else if (!this._to) {
|
||||
throw new Error('RemoteMessage: Missing required `to` property');
|
||||
} else if (!this.ttl) {
|
||||
} else if (!this._ttl) {
|
||||
throw new Error('RemoteMessage: Missing required `ttl` property');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user