App.js 8.54 KB
Newer Older
renato's avatar
renato committed
1 2 3 4 5 6 7 8 9 10 11
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  TouchableOpacity,
12
  View,
Libin Lu's avatar
Libin Lu committed
13 14
  Clipboard,
  Platform
renato's avatar
renato committed
15 16
} from 'react-native';

Libin Lu's avatar
Libin Lu committed
17 18
import { StackNavigator } from 'react-navigation';

Libin Lu's avatar
Libin Lu committed
19
import FCM, {NotificationActionType} from "react-native-fcm";
Libin Lu's avatar
Libin Lu committed
20

Libin Lu's avatar
Libin Lu committed
21
import {registerKilledListener, registerAppListener} from "./Listeners";
renato's avatar
renato committed
22 23
import firebaseClient from  "./FirebaseClient";

Libin Lu's avatar
Libin Lu committed
24 25
registerKilledListener();

Libin Lu's avatar
Libin Lu committed
26
class MainPage extends Component {
27 28 29 30
  constructor(props) {
    super(props);

    this.state = {
31 32
      token: "",
      tokenCopyFeedback: ""
33 34 35
    }
  }

Libin Lu's avatar
Libin Lu committed
36
  async componentDidMount(){
Libin Lu's avatar
Libin Lu committed
37
    registerAppListener(this.props.navigation);
Libin Lu's avatar
Libin Lu committed
38 39 40 41
    FCM.getInitialNotification().then(notif => {
      this.setState({
        initNotif: notif
      })
Libin Lu's avatar
Libin Lu committed
42
      if(notif && notif.targetScreen === 'detail'){
Libin Lu's avatar
Libin Lu committed
43 44 45 46
        setTimeout(()=>{
          this.props.navigation.navigate('Detail')
        }, 500)
      }
Libin Lu's avatar
Libin Lu committed
47
    });
Libin Lu's avatar
Libin Lu committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

    try{
      let result = await FCM.requestPermissions({badge: false, sound: true, alert: true});
    } catch(e){
      console.error(e);
    }

    FCM.getFCMToken().then(token => {
      console.log("TOKEN (getFCMToken)", token);
      this.setState({token: token || ""})
    });

    if(Platform.OS === 'ios'){
      FCM.getAPNSToken().then(token => {
        console.log("APNS TOKEN (getFCMToken)", token);
      });
    }
Libin Lu's avatar
Libin Lu committed
65 66
  }

Libin Lu's avatar
Libin Lu committed
67 68
  showLocalNotification() {
    FCM.presentLocalNotification({
Libin Lu's avatar
Libin Lu committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
      id: "UNIQ_ID_STRING",                               // (optional for instant notification)
      title: "Test Notification with action",             // as FCM payload
      body: "Force touch to reply",                       // as FCM payload (required)
      sound: "bell.mp3",                                  // "default" or filename
      priority: "high",                                   // as FCM payload
      click_action: "com.myapp.MyCategory",               // as FCM payload - this is used as category identifier on iOS.
      badge: 10,                                          // as FCM payload IOS only, set 0 to clear badges
      number: 10,                                         // Android only
      ticker: "My Notification Ticker",                   // Android only
      auto_cancel: true,                                  // Android only (default true)
      large_icon: "https://image.freepik.com/free-icon/small-boy-cartoon_318-38077.jpg",                           // Android only
      icon: "ic_launcher",                                // as FCM payload, you can relace this with custom icon you put in mipmap
      big_text: "Show when notification is expanded",     // Android only
      sub_text: "This is a subText",                      // Android only
      color: "red",                                       // Android only
      vibrate: 300,                                       // Android only default: 300, no vibration if you pass 0
      wake_screen: true,                                  // Android only, wake up screen when notification arrives
      group: "group",                                     // Android only
      picture: "https://google.png",                      // Android only bigPicture style
      ongoing: true,                                      // Android only
      my_custom_data:'my_custom_field_value',             // extra data you want to throw
      lights: true,                                       // Android only, LED blinking (default false)
      show_in_foreground: true                           // notification when app is in foreground (local & remote)
Libin Lu's avatar
Libin Lu committed
92 93 94
    });
  }

Libin Lu's avatar
Libin Lu committed
95 96 97 98 99 100 101
  scheduleLocalNotification() {
    FCM.scheduleLocalNotification({
      id: 'testnotif',
      fire_date: new Date().getTime()+5000,
      vibrate: 500,
      title: 'Hello',
      body: 'Test Scheduled Notification',
Libin Lu's avatar
Libin Lu committed
102
      sub_text: 'sub text',
Libin Lu's avatar
Libin Lu committed
103
      priority: "high",
Libin Lu's avatar
Libin Lu committed
104
      large_icon: "https://image.freepik.com/free-icon/small-boy-cartoon_318-38077.jpg",
Libin Lu's avatar
Libin Lu committed
105
      show_in_foreground: true,
Libin Lu's avatar
Libin Lu committed
106
      picture: 'https://firebase.google.com/_static/af7ae4b3fc/images/firebase/lockup.png',
Libin Lu's avatar
Libin Lu committed
107 108 109
      wake_screen: true,
      extra1: {a: 1},
      extra2: 1
Libin Lu's avatar
Libin Lu committed
110 111 112
    });
  }

Libin Lu's avatar
Libin Lu committed
113 114 115 116 117 118 119 120 121
  sendRemoteNotification(token) {
    let body;

    if(Platform.OS === 'android'){
      body = {
        "to": token,
      	"data":{
					"custom_notification": {
						"title": "Simple FCM Client",
Libin Lu's avatar
Libin Lu committed
122
						"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
123 124
						"sound": "default",
						"priority": "high",
Libin Lu's avatar
Libin Lu committed
125 126
            "show_in_foreground": true,
            targetScreen: 'detail'
Libin Lu's avatar
Libin Lu committed
127 128 129 130 131 132 133 134 135
        	}
    		},
    		"priority": 10
      }
    } else {
			body = {
				"to": token,
				"notification":{
					"title": "Simple FCM Client",
Libin Lu's avatar
Libin Lu committed
136
					"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
137
					"sound": "default"
Libin Lu's avatar
Libin Lu committed
138 139 140 141
        },
        data: {
          targetScreen: 'detail'
        },
Libin Lu's avatar
Libin Lu committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
				"priority": 10
			}
		}

    firebaseClient.send(JSON.stringify(body), "notification");
  }

  sendRemoteData(token) {
    let body = {
    	"to": token,
      "data":{
    		"title": "Simple FCM Client",
    		"body": "This is a notification with only DATA.",
    		"sound": "default"
    	},
    	"priority": "normal"
    }

    firebaseClient.send(JSON.stringify(body), "data");
  }

Libin Lu's avatar
Libin Lu committed
163 164 165 166 167 168
  showLocalNotificationWithAction() {
    FCM.presentLocalNotification({
      title: 'Test Notification with action',
      body: 'Force touch to reply',
      priority: "high",
      show_in_foreground: true,
Libin Lu's avatar
Libin Lu committed
169 170 171 172 173 174 175 176
      click_action: "com.myidentifi.fcm.text", // for ios
      android_actions: JSON.stringify([{
        id: "view",
        title: 'view'
      },{
        id: "dismiss",
        title: 'dismiss'
      }]) // for android, take syntax similar to ios's. only buttons are supported
Libin Lu's avatar
Libin Lu committed
177
    });
Libin Lu's avatar
Libin Lu committed
178 179
  }

renato's avatar
renato committed
180
  render() {
181
    let { token, tokenCopyFeedback } = this.state;
182

renato's avatar
renato committed
183 184 185 186 187 188
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to Simple Fcm Client!
        </Text>

189 190 191 192
        <Text style={styles.feedback}>
          {this.state.tokenCopyFeedback}
        </Text>

Libin Lu's avatar
Libin Lu committed
193 194 195 196
        <Text style={styles.feedback}>
          Remote notif won't be available to iOS emulators
        </Text>

Libin Lu's avatar
Libin Lu committed
197
        <TouchableOpacity onPress={() => this.sendRemoteNotification(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
198
          <Text style={styles.buttonText}>Send Remote Notification</Text>
renato's avatar
renato committed
199 200
        </TouchableOpacity>

Libin Lu's avatar
Libin Lu committed
201
        <TouchableOpacity onPress={() => this.sendRemoteData(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
202
          <Text style={styles.buttonText}>Send Remote Data</Text>
renato's avatar
renato committed
203
        </TouchableOpacity>
renato's avatar
renato committed
204

Libin Lu's avatar
Libin Lu committed
205 206
        <TouchableOpacity onPress={() => this.showLocalNotification()} style={styles.button}>
          <Text style={styles.buttonText}>Show Local Notification</Text>
renato's avatar
renato committed
207
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
208

Libin Lu's avatar
Libin Lu committed
209
        <TouchableOpacity onPress={() => this.showLocalNotificationWithAction(token)} style={styles.button}>
Libin Lu's avatar
Libin Lu committed
210
          <Text style={styles.buttonText}>Show Local Notification with Action</Text>
Libin Lu's avatar
Libin Lu committed
211
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
212 213 214 215

        <TouchableOpacity onPress={() => this.scheduleLocalNotification()} style={styles.button}>
          <Text style={styles.buttonText}>Schedule Notification in 5s</Text>
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
216 217 218 219 220 221 222 223 224

        <Text>
          Init notif: {JSON.stringify(this.state.initNotif)}
        </Text>

        <Text selectable={true} onPress={() => this.setClipboardContent(this.state.token)} style={styles.instructions}>
          Token: {this.state.token}
        </Text>

renato's avatar
renato committed
225 226 227
      </View>
    );
  }
228 229 230 231 232 233 234 235 236 237

  setClipboardContent(text) {
    Clipboard.setString(text);
    this.setState({tokenCopyFeedback: "Token copied to clipboard."});
    setTimeout(() => {this.clearTokenCopyFeedback()}, 2000);
  }

  clearTokenCopyFeedback() {
    this.setState({tokenCopyFeedback: ""});
  }
renato's avatar
renato committed
238 239
}

Libin Lu's avatar
Libin Lu committed
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
class DetailPage extends Component {
  render(){
    return <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Detail page</Text>
    </View>
  }
}

export default StackNavigator({
  Main: {
    screen: MainPage,
  },
  Detail: {
    screen: DetailPage
  }
}, {
  initialRouteName: 'Main',
});

renato's avatar
renato committed
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
274 275 276 277 278 279
    marginBottom: 2,
  },
  feedback: {
    textAlign: 'center',
    color: '#996633',
    marginBottom: 3,
renato's avatar
renato committed
280 281 282 283 284
  },
  button: {
    backgroundColor: "teal",
    paddingHorizontal: 20,
    paddingVertical: 10,
renato's avatar
renato committed
285
    marginVertical: 15,
renato's avatar
renato committed
286 287 288 289 290 291 292
    borderRadius: 10
  },
  buttonText: {
    color: "white",
    backgroundColor: "transparent"
  },
});