nfcim / flutter_nfc_kit

Flutter plugin to provide NFC functionality on Android and iOS, including reading metadata, read & write NDEF records, and transceive layer 3 & 4 data with NFC tags / cards
https://pub.dev/packages/flutter_nfc_kit
MIT License
200 stars 121 forks source link

NFC Write - Text Record fails on Example App #38

Closed ampcontroljeff closed 3 years ago

ampcontroljeff commented 3 years ago

Hi, On the example app, i try and write an text record with "Hello World" and I get the following errors.

image

image

Harry-Chen commented 3 years ago

@Chever-John Please check this out.

Harry-Chen commented 3 years ago

This might be a regression when migrating to null-safety. We will fix it ASAP.

liveaffiliates commented 3 years ago

I had the same problem.

Looks like the id is coming back as null, but there is nowhere to set the id?

image

If you read the result you get:

TextRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=T encoding=UTF-8 language=en text=hello world

The problem is with the Uint8List? id; one of the parameters for NDEFRecord. is null

This getter idString will show is as '(Empty)' when id is null (as per below):

 /// Hex String of id, return "(empty)" when the id bytes is null
  String get idString {
    return id?.toHexString() ?? '(empty)';
  }

But In the main.dart file the Text Widget doesn't reference the Getter idString and converts to hex string (But it cant because this is null):

id:${_records![index].id!.toHexString()

instead the getter idString like this, which will clear up the problem above:

id:${_records![index].idString

But the problem runs further than just the displaying of the record because the null Uint8List? id being pass to the writeNDEF function:

The null value for id is sent to the writeNDEF function:

 static Future<void> writeNDEFRecords(List<ndef.NDEFRecord> message) async {
    return await writeNDEFRawRecords(message.map((r) => r.toRaw()).toList());
  }

That in converts it to raw, the problem is in the conversion function as well:

 NDEFRawRecord toRaw() {
    return NDEFRawRecord(id!.toHexString(), payload!.toHexString(),
        type!.toHexString(), this.tnf);
  }

This is running a null check on id which causes it to fail, se below I hard coded the string 'id' as a Uint8List and it fixes the problem and allows it to write again:

 NDEFRawRecord toRaw() {
    return NDEFRawRecord(Uint8List.fromList('id'.codeUnits).toHexString(), payload!.toHexString(),
        type!.toHexString(), this.tnf);
  }

It seem like for the main you can just use the getter, and for the creation or at raw conversion end you can set a default value for id.

Thanks

Harry-Chen commented 3 years ago

@liveaffiliates Wow, really thanks for your analysis!

Chever-John commented 3 years ago

@liveaffiliates Thank you very much for your detailed analysis, and it really helped me a lot. We will fix this problem as soon as possible.

liveaffiliates commented 3 years ago

@Harry-Chen @Chever-John Thanks for making and working on the project. Did you end up adding changes to the library?

Harry-Chen commented 3 years ago

@Harry-Chen @Chever-John Thanks for making and working on the project. Did you end up adding changes to the library?

Thanks for your reminder! @Chever-John have fixed it but I forgot to merge & publish. I will deal with it soon.

liveaffiliates commented 3 years ago

@Chever-John awesome, thanks!

Harry-Chen commented 3 years ago

Fixed in e0b61087 and released in v3.0.1. Please check whether it is working now.

liveaffiliates commented 3 years ago

@Harry-Chen ok will cill check in a few hours thanks

Harry-Chen commented 3 years ago

I suppose it is now fixed.

liveaffiliates commented 3 years ago

I suppose it is now fixed.

Hi, Tested on Android. Had trouble installing it on iOS because of the minimum ios13 requirement. Only fixed the build today, testing on Monday. Will let you know if there are any issues. Thanks