NFC reading and writing [SOLVED]

Hi,

does anybody know how to implement writing to NFC correctly in Ionic 2? This following example does write a tag, but if you try to write another one, the app crashes. Tried with two different android mobilephones.

// removed bad code from here. See a working solution below.

If somebody is struggling with the same problem, I think this has something to do with that how the addNdefListener fires multiple times. Maybe couple of if statements will solve this. Troubleshooting continues after the weekend.

1 Like

Okay, I got it finally working. Here is working example for anyone wondering how to use NFC reading and writing in ionic 2. Always remember to unsubscribe NdefListener or it will stay alive even if you close the page.

I removed some parts from this, but here should be working skeleton to work with.

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

// plugins
import { NFC, Ndef } from '@ionic-native/nfc';

import { Subscription } from 'rxjs/Rx'

@IonicPage()
@Component({
  selector: 'page-nfc',
  templateUrl: 'nfc.html',
})
export class NfcPage {

  readingTag:   boolean   = false;
  writingTag:   boolean   = false;
  isWriting:    boolean   = false;
  ndefMsg:      string    = '';
  subscriptions: Array<Subscription> = new Array<Subscription>();

  constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    public nfc: NFC,
    public ndef: Ndef) {

      this.subscriptions.push(this.nfc.addNdefListener()
        .subscribe(data => {
          if (this.readingTag) {
            let payload = data.tag.ndefMessage[0].payload;
            let tagContent = this.nfc.bytesToString(payload).substring(3);
            this.readingTag = false;
            console.log("tag data", tagContent);
          } 
          else if (this.writingTag) {
            if (!this.isWriting) {
              this.isWriting = true;
              this.nfc.write([this.ndefMsg])
                .then(() => {
                  this.writingTag = false;
                  this.isWriting = false;
                  console.log("written");
                })
                .catch(err => {
                  this.writingTag = false;
                  this.isWriting = false;
                });
            }
          }
        },
        err => {
        
        })
     );
  }

  ionViewWillLeave() {
    this.subscriptions.forEach(sub => {
      sub.unsubscribe();
    });
  }

  readTag() {
    this.readingTag = true;
  }

  writeTag(writeText: string) {
    this.writingTag = true;
    this.ndefMsg = this.ndef.textRecord(writeText);
  }
}

2 Likes

This solution is perfect. For me actually i’m using platform ready to initiate the NFC. So it still works :smiley: Thanks twix !

ionViewWillEnter() {
        this.platform.ready().then(() => {
            this.cekNFC();
        });
    }

Can you please send the full source code. As I am unable to get you point.

Hi all,
I’m trying to share data between the two nfc devices. I don’t how to do that.Please help with that.
Thanks

I am trying to figure this out as well

can you post full source code?

Im stuck for weeks with NFC. Simply doens’t work on my real device Samsung S7 Edge.

Thnks,.

Here is the Full Code.

App.module.ts
import { NgModule, ErrorHandler } from ‘@angular/core’;
import { BrowserModule } from ‘@angular/platform-browser’;
import { RouteReuseStrategy } from ‘@angular/router’;

import { IonicModule, IonicRouteStrategy } from ‘@ionic/angular’;
import { SplashScreen } from ‘@ionic-native/splash-screen/ngx’;
import { StatusBar } from ‘@ionic-native/status-bar/ngx’;

import { AppRoutingModule } from ‘./app-routing.module’;
import { AppComponent } from ‘./app.component’;

import {NFC, Ndef} from ‘@ionic-native/nfc/ngx’;

@NgModule({
declarations: [AppComponent],
entryComponents: ,
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
NFC,
Ndef,
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}

Mainpage.ts

import { Component } from ‘@angular/core’;
import { NFC, Ndef } from ‘@ionic-native/nfc/ngx’;
import { NavController, Platform, AlertController, ToastController } from ‘@ionic/angular’;
import { ChangeDetectorRef } from ‘@angular/core’;

@Component({
selector: ‘app-tabs’,
templateUrl: ‘tabs.page.html’,
styleUrls: [‘tabs.page.scss’]
})
export class TabsPage {
tagid: any;
tagdesc: any;
constructor(public platform: Platform,
private alertCtrl: AlertController,
private toastCtrl: ToastController,
public navCtrl: NavController,
private nfc: NFC,
private ndef: Ndef,
private cdr: ChangeDetectorRef) {
this.platform.ready().then(() => {
this.addListenNFC();
});
}
addListenNFC() {
console.log(‘enter into a addListenNFC’);
this.tagid = “”;
this.tagdesc = “”;

  this.nfc.addNdefListener(() => {
    console.log('successfully attached ndef listener');
  }, async (err) => {
    console.log('error attaching ndef listener', err);

    let toast = this.toastCtrl.create({
      message: err,
      duration: 1000,
      position: 'bottom'
    });

    return (await toast).present(); 

  }).subscribe(async (event) => {
    console.log('received ndef message. the tag contains: ', event.tag);
    console.log('decoded tag id', this.nfc.bytesToHexString(event.tag.id));
    this.tagid = "";
    this.tagdesc = "";
    let tagId = await this.nfc.bytesToHexString(event.tag.id);
    this.tagid = tagId;
    if (event.tag.ndefMessage) {
    let payload = event.tag.ndefMessage[0].payload;
     let tagContent = await this.nfc.bytesToString(payload).substring(3);
     this.tagdesc = tagContent;
    }

    let toast = this.toastCtrl.create({
      message: this.nfc.bytesToHexString(event.tag.id),
      //message: this.nfc.bytesToHexString(event.tag.ndefMessage[0].payload) && " --- " && this.nfc.bytesToHexString(event.tag.id) ,
      duration: 5000,
      position: 'bottom'
    });
    (await toast).present(); 
    this.cdr.detectChanges();
  });

}

}