App.js 8.73 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
  Clipboard,
Libin Lu's avatar
Libin Lu committed
14 15
  Platform,
  ScrollView
renato's avatar
renato committed
16 17
} from 'react-native';

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

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

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

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

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

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

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

    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
66 67
  }

Libin Lu's avatar
Libin Lu committed
68 69
  showLocalNotification() {
    FCM.presentLocalNotification({
Libin Lu's avatar
Libin Lu committed
70
      id: new Date().valueOf().toString(),                // (optional for instant notification)
Libin Lu's avatar
Libin Lu committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
      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
93 94 95
    });
  }

Libin Lu's avatar
Libin Lu committed
96 97 98 99 100 101 102
  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
103
      sub_text: 'sub text',
Libin Lu's avatar
Libin Lu committed
104
      priority: "high",
Libin Lu's avatar
Libin Lu committed
105
      large_icon: "https://image.freepik.com/free-icon/small-boy-cartoon_318-38077.jpg",
Libin Lu's avatar
Libin Lu committed
106
      show_in_foreground: true,
Libin Lu's avatar
Libin Lu committed
107
      picture: 'https://firebase.google.com/_static/af7ae4b3fc/images/firebase/lockup.png',
Libin Lu's avatar
Libin Lu committed
108 109 110
      wake_screen: true,
      extra1: {a: 1},
      extra2: 1
Libin Lu's avatar
Libin Lu committed
111 112 113
    });
  }

Libin Lu's avatar
Libin Lu committed
114 115 116 117 118 119 120 121 122
  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
123
						"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
124 125
						"sound": "default",
						"priority": "high",
Libin Lu's avatar
Libin Lu committed
126 127
            "show_in_foreground": true,
            targetScreen: 'detail'
Libin Lu's avatar
Libin Lu committed
128 129 130 131 132 133 134 135 136
        	}
    		},
    		"priority": 10
      }
    } else {
			body = {
				"to": token,
				"notification":{
					"title": "Simple FCM Client",
Libin Lu's avatar
Libin Lu committed
137
					"body": "Click me to go to detail",
Libin Lu's avatar
Libin Lu committed
138
					"sound": "default"
Libin Lu's avatar
Libin Lu committed
139 140 141 142
        },
        data: {
          targetScreen: 'detail'
        },
Libin Lu's avatar
Libin Lu committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
				"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
164 165 166 167 168 169
  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
170 171 172 173 174 175 176 177
      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
178
    });
Libin Lu's avatar
Libin Lu committed
179 180
  }

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

renato's avatar
renato committed
184 185
    return (
      <View style={styles.container}>
Libin Lu's avatar
Libin Lu committed
186
      <ScrollView style={{paddingHorizontal: 20}}>
renato's avatar
renato committed
187 188 189 190
        <Text style={styles.welcome}>
          Welcome to Simple Fcm Client!
        </Text>

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

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

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

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

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

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

        <TouchableOpacity onPress={() => this.scheduleLocalNotification()} style={styles.button}>
          <Text style={styles.buttonText}>Schedule Notification in 5s</Text>
        </TouchableOpacity>
Libin Lu's avatar
Libin Lu committed
218

Libin Lu's avatar
Libin Lu committed
219 220 221
        <Text style={styles.instructions}>
          Init notif:
        </Text>
Libin Lu's avatar
Libin Lu committed
222
        <Text>
Libin Lu's avatar
Libin Lu committed
223
          {JSON.stringify(this.state.initNotif)}
Libin Lu's avatar
Libin Lu committed
224 225
        </Text>

Libin Lu's avatar
Libin Lu committed
226 227
        <Text style={styles.instructions}>
          Token:
Libin Lu's avatar
Libin Lu committed
228
        </Text>
Libin Lu's avatar
Libin Lu committed
229 230 231 232
        <Text selectable={true} onPress={() => this.setClipboardContent(this.state.token)}>
          {this.state.token}
        </Text>
        </ScrollView>
renato's avatar
renato committed
233 234 235
      </View>
    );
  }
236 237 238 239 240 241 242 243 244 245

  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
246 247
}

Libin Lu's avatar
Libin Lu committed
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
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
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
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',
282 283 284 285 286 287
    marginBottom: 2,
  },
  feedback: {
    textAlign: 'center',
    color: '#996633',
    marginBottom: 3,
renato's avatar
renato committed
288 289 290 291
  },
  button: {
    backgroundColor: "teal",
    paddingHorizontal: 20,
Libin Lu's avatar
Libin Lu committed
292 293
    paddingVertical: 15,
    marginVertical: 10,
renato's avatar
renato committed
294 295 296 297 298 299 300
    borderRadius: 10
  },
  buttonText: {
    color: "white",
    backgroundColor: "transparent"
  },
});